From 8dc1b995863426067ff10afacea459062c71c3df Mon Sep 17 00:00:00 2001 From: plegall Date: Mon, 8 Mar 2010 23:39:53 +0000 Subject: feature 1489: integrate UploadForm into Piwigo core. The integration is not 100% done, I just "made it work" on trunk. pclzip library was updated to version 2.8.2 for memory usage improvement. git-svn-id: http://piwigo.org/svn/trunk@5089 68402e56-0260-453c-a942-63ccdbb3a9ee --- admin/include/functions_upload.inc.php | 264 + admin/include/pclzip.lib.php | 7740 ++++++++++++-------- admin/include/uploadify/cancel.png | Bin 0 -> 778 bytes .../uploadify/jquery.uploadify.v2.1.0.min.js | 26 + admin/include/uploadify/swfobject.js | 4 + admin/include/uploadify/uploadify.css | 60 + admin/include/uploadify/uploadify.php | 44 + admin/include/uploadify/uploadify.swf | Bin 0 -> 23119 bytes admin/photos_add.php | 199 + admin/photos_add_direct.php | 488 ++ admin/photos_add_settings.php | 155 + admin/template/goto/admin.tpl | 1 + admin/template/goto/default-layout.css | 51 +- admin/template/goto/photos_add_direct.tpl | 185 + admin/template/goto/photos_add_settings.tpl | 74 + 15 files changed, 6339 insertions(+), 2952 deletions(-) create mode 100644 admin/include/functions_upload.inc.php create mode 100644 admin/include/uploadify/cancel.png create mode 100644 admin/include/uploadify/jquery.uploadify.v2.1.0.min.js create mode 100644 admin/include/uploadify/swfobject.js create mode 100644 admin/include/uploadify/uploadify.css create mode 100644 admin/include/uploadify/uploadify.php create mode 100644 admin/include/uploadify/uploadify.swf create mode 100644 admin/photos_add.php create mode 100644 admin/photos_add_direct.php create mode 100644 admin/photos_add_settings.php create mode 100644 admin/template/goto/photos_add_direct.tpl create mode 100644 admin/template/goto/photos_add_settings.tpl (limited to 'admin') diff --git a/admin/include/functions_upload.inc.php b/admin/include/functions_upload.inc.php new file mode 100644 index 000000000..39259ad34 --- /dev/null +++ b/admin/include/functions_upload.inc.php @@ -0,0 +1,264 @@ + isset($original_filename) ? $original_filename : basename($file_path), + 'date_available' => $dbnow, + 'tn_ext' => 'jpg', + 'path' => preg_replace('/^.*?upload/', './upload', $file_path), + 'filesize' => $file_infos['filesize'], + 'width' => $file_infos['width'], + 'height' => $file_infos['height'], + 'md5sum' => $md5sum, + ); + + if (isset($high_infos)) + { + $insert['has_high'] = 'true'; + $insert['high_filesize'] = $high_infos['filesize']; + } + + if (isset($level)) + { + $insert['level'] = $level; + } + + mass_inserts( + IMAGES_TABLE, + array_keys($insert), + array($insert) + ); + + $image_id = mysql_insert_id(); + + if (isset($categories) and count($categories) > 0) + { + associate_images_to_categories( + array($image_id), + $categories + ); + } + + // update metadata from the uploaded file (exif/iptc) + update_metadata(array($image_id=>$file_path)); + + invalidate_user_cache(); + + return $image_id; +} + +function prepare_directory($directory) +{ + if (!is_dir($directory)) { + umask(0000); + $recursive = true; + if (!@mkdir($directory, 0777, $recursive)) + { + die('[prepare_directory] cannot create directory "'.$directory.'"'); + } + } + + if (!is_writable($directory)) + { + // last chance to make the directory writable + @chmod($directory, 0777); + + if (!is_writable($directory)) + { + die('[prepare_directory] directory "'.$directory.'" has no write access'); + } + } + + secure_directory($directory); +} + +function need_resize($image_filepath, $max_width, $max_height) +{ + list($width, $height) = getimagesize($image_filepath); + + if ($width > $max_width or $height > $max_height) + { + return true; + } + + return false; +} + +function pwg_image_resize($source_filepath, $destination_filepath, $max_width, $max_height, $quality) +{ + if (!function_exists('gd_info')) + { + return false; + } + + // extension of the picture filename + $extension = strtolower(get_extension($source_filepath)); + + $source_image = null; + if (in_array($extension, array('jpg', 'jpeg'))) + { + $source_image = @imagecreatefromjpeg($source_filepath); + } + else if ($extension == 'png') + { + $source_image = @imagecreatefrompng($source_filepath); + } + else + { + die('unsupported file extension'); + } + + // width/height + $source_width = imagesx($source_image); + $source_height = imagesy($source_image); + + $ratio_width = $source_width / $max_width; + $ratio_height = $source_height / $max_height; + + // maximal size exceeded ? + if ($ratio_width > 1 or $ratio_height > 1) + { + if ($ratio_width < $ratio_height) + { + $destination_width = ceil($source_width / $ratio_height); + $destination_height = $max_height; + } + else + { + $destination_width = $max_width; + $destination_height = ceil($source_height / $ratio_width); + } + } + else + { + // the image doesn't need any resize! We just copy it to the destination + copy($source_filepath, $destination_filepath); + return true; + } + + $destination_image = imagecreatetruecolor($destination_width, $destination_height); + + imagecopyresampled( + $destination_image, + $source_image, + 0, + 0, + 0, + 0, + $destination_width, + $destination_height, + $source_width, + $source_height + ); + + imagejpeg($destination_image, $destination_filepath, $quality); + // freeing memory ressources + imagedestroy($source_image); + imagedestroy($destination_image); + + // everything should be OK if we are here! + return true; +} + +function pwg_image_infos($path) +{ + list($width, $height) = getimagesize($path); + $filesize = floor(filesize($path)/1024); + + return array( + 'width' => $width, + 'height' => $height, + 'filesize' => $filesize, + ); +} + +function is_valid_image_extension($extension) +{ + return in_array(strtolower($extension), array('jpg', 'jpeg', 'png')); +} +?> \ No newline at end of file diff --git a/admin/include/pclzip.lib.php b/admin/include/pclzip.lib.php index c7a7cbc1b..e7facc1ea 100644 --- a/admin/include/pclzip.lib.php +++ b/admin/include/pclzip.lib.php @@ -1,6 +1,6 @@ zipname = $p_zipname; - $this->zip_fd = 0; - $this->magic_quotes_status = -1; +// -------------------------------------------------------------------------------- +// ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED ***** +// -------------------------------------------------------------------------------- - return; -} + // ----- Global variables + $g_pclzip_version = "2.8.2"; + + // ----- Error codes + // -1 : Unable to open file in binary write mode + // -2 : Unable to open file in binary read mode + // -3 : Invalid parameters + // -4 : File does not exist + // -5 : Filename is too long (max. 255) + // -6 : Not a valid zip file + // -7 : Invalid extracted file size + // -8 : Unable to create directory + // -9 : Invalid archive extension + // -10 : Invalid archive format + // -11 : Unable to delete file (unlink) + // -12 : Unable to rename file (rename) + // -13 : Invalid header checksum + // -14 : Invalid archive size + define( 'PCLZIP_ERR_USER_ABORTED', 2 ); + define( 'PCLZIP_ERR_NO_ERROR', 0 ); + define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 ); + define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 ); + define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 ); + define( 'PCLZIP_ERR_MISSING_FILE', -4 ); + define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 ); + define( 'PCLZIP_ERR_INVALID_ZIP', -6 ); + define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 ); + define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 ); + define( 'PCLZIP_ERR_BAD_EXTENSION', -9 ); + define( 'PCLZIP_ERR_BAD_FORMAT', -10 ); + define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 ); + define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 ); + define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 ); + define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 ); + define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 ); + define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 ); + define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 ); + define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 ); + define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 ); + define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 ); + define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 ); + + // ----- Options values + define( 'PCLZIP_OPT_PATH', 77001 ); + define( 'PCLZIP_OPT_ADD_PATH', 77002 ); + define( 'PCLZIP_OPT_REMOVE_PATH', 77003 ); + define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 ); + define( 'PCLZIP_OPT_SET_CHMOD', 77005 ); + define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 ); + define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 ); + define( 'PCLZIP_OPT_BY_NAME', 77008 ); + define( 'PCLZIP_OPT_BY_INDEX', 77009 ); + define( 'PCLZIP_OPT_BY_EREG', 77010 ); + define( 'PCLZIP_OPT_BY_PREG', 77011 ); + define( 'PCLZIP_OPT_COMMENT', 77012 ); + define( 'PCLZIP_OPT_ADD_COMMENT', 77013 ); + define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 ); + define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 ); + define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 ); + define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 ); + // Having big trouble with crypt. Need to multiply 2 long int + // which is not correctly supported by PHP ... + //define( 'PCLZIP_OPT_CRYPT', 77018 ); + define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 ); + define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 ); + define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias + define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 ); + define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias + define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 ); + define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias + + // ----- File description attributes + define( 'PCLZIP_ATT_FILE_NAME', 79001 ); + define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 ); + define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 ); + define( 'PCLZIP_ATT_FILE_MTIME', 79004 ); + define( 'PCLZIP_ATT_FILE_CONTENT', 79005 ); + define( 'PCLZIP_ATT_FILE_COMMENT', 79006 ); + + // ----- Call backs values + define( 'PCLZIP_CB_PRE_EXTRACT', 78001 ); + define( 'PCLZIP_CB_POST_EXTRACT', 78002 ); + define( 'PCLZIP_CB_PRE_ADD', 78003 ); + define( 'PCLZIP_CB_POST_ADD', 78004 ); + /* For futur use + define( 'PCLZIP_CB_PRE_LIST', 78005 ); + define( 'PCLZIP_CB_POST_LIST', 78006 ); + define( 'PCLZIP_CB_PRE_DELETE', 78007 ); + define( 'PCLZIP_CB_POST_DELETE', 78008 ); + */ -function create($p_filelist) -{ - $v_result=1; + // -------------------------------------------------------------------------------- + // Class : PclZip + // Description : + // PclZip is the class that represent a Zip archive. + // The public methods allow the manipulation of the archive. + // Attributes : + // Attributes must not be accessed directly. + // Methods : + // PclZip() : Object creator + // create() : Creates the Zip archive + // listContent() : List the content of the Zip archive + // extract() : Extract the content of the archive + // properties() : List the properties of the archive + // -------------------------------------------------------------------------------- + class PclZip + { + // ----- Filename of the zip file + var $zipname = ''; - $this->privErrorReset(); + // ----- File descriptor of the zip file + var $zip_fd = 0; - $v_options = array(); - $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + // ----- Internal error handling + var $error_code = 1; + var $error_string = ''; + + // ----- Current status of the magic_quotes_runtime + // This value store the php configuration for magic_quotes + // The class can then disable the magic_quotes and reset it after + var $magic_quotes_status; + + // -------------------------------------------------------------------------------- + // Function : PclZip() + // Description : + // Creates a PclZip object and set the name of the associated Zip archive + // filename. + // Note that no real action is taken, if the archive does not exist it is not + // created. Use create() for that. + // -------------------------------------------------------------------------------- + function PclZip($p_zipname) + { - $v_size = func_num_args(); + // ----- Tests the zlib + if (!function_exists('gzopen')) + { + die('Abort '.basename(__FILE__).' : Missing zlib extensions'); + } - if ($v_size > 1) { - $v_arg_list = func_get_args(); + // ----- Set the attributes + $this->zipname = $p_zipname; + $this->zip_fd = 0; + $this->magic_quotes_status = -1; + + // ----- Return + return; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // create($p_filelist, $p_add_dir="", $p_remove_dir="") + // create($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two different synopsis. The first one is historical. + // This method creates a Zip Archive. The Zip file is created in the + // filesystem. The files and directories indicated in $p_filelist + // are added in the archive. See the parameters description for the + // supported format of $p_filelist. + // When a directory is in the list, the directory and its content is added + // in the archive. + // In this synopsis, the function takes an optional variable list of + // options. See bellow the supported options. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function create($p_filelist) + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove from the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + //, PCLZIP_OPT_CRYPT => 'optional' + )); + if ($v_result != 1) { + return 0; + } + } - array_shift($v_arg_list); - $v_size--; + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_ADD => 'optional', - PCLZIP_CB_POST_ADD => 'optional', - PCLZIP_OPT_NO_COMPRESSION => 'optional', - PCLZIP_OPT_COMMENT => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - )); - if ($v_result != 1) { - return 0; + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + } + else if ($v_size > 2) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Invalid number / type of arguments"); + return 0; + } } } - - else { - - $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; - - if ($v_size == 2) { - $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; } - else if ($v_size > 2) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, - "Invalid number / type of arguments"); - return 0; + + // ----- The list is a list of string names + else { + $v_string_list = $p_filelist; } } - } - - $this->privOptionDefaultThreshold($v_options); - $v_string_list = array(); - $v_att_list = array(); - $v_filedescr_list = array(); - $p_result_list = array(); - - if (is_array($p_filelist)) { - - if (isset($p_filelist[0]) && is_array($p_filelist[0])) { - $v_att_list = $p_filelist; + // ----- Look if the $p_filelist is a string + else if (is_string($p_filelist)) { + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); } - + + // ----- Invalid variable type for $p_filelist else { - $v_string_list = $p_filelist; + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); + return 0; } - } - - else if (is_string($p_filelist)) { - $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); - } - - else { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); - return 0; - } - - if (sizeof($v_string_list) != 0) { - foreach ($v_string_list as $v_string) { - if ($v_string != '') { - $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + if ($v_string != '') { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } + else { + } } - else { + } + + // ----- For each file in the list check the attributes + $v_supported_attributes + = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' + ,PCLZIP_ATT_FILE_MTIME => 'optional' + ,PCLZIP_ATT_FILE_CONTENT => 'optional' + ,PCLZIP_ATT_FILE_COMMENT => 'optional' + ); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, + $v_filedescr_list[], + $v_options, + $v_supported_attributes); + if ($v_result != 1) { + return 0; } } - } - - $v_supported_attributes - = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' - ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' - ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' - ,PCLZIP_ATT_FILE_MTIME => 'optional' - ,PCLZIP_ATT_FILE_CONTENT => 'optional' - ,PCLZIP_ATT_FILE_COMMENT => 'optional' - ); - foreach ($v_att_list as $v_entry) { - $v_result = $this->privFileDescrParseAtt($v_entry, - $v_filedescr_list[], - $v_options, - $v_supported_attributes); + + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); if ($v_result != 1) { return 0; } - } - - $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); - if ($v_result != 1) { - return 0; - } - - $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); - if ($v_result != 1) { - return 0; - } - - return $p_result_list; -} - -function add($p_filelist) -{ - $v_result=1; - - $this->privErrorReset(); - $v_options = array(); - $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + // ----- Call the create fct + $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); + if ($v_result != 1) { + return 0; + } - $v_size = func_num_args(); + // ----- Return + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // add($p_filelist, $p_add_dir="", $p_remove_dir="") + // add($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two synopsis. The first one is historical. + // This methods add the list of files in an existing archive. + // If a file with the same name already exists, it is added at the end of the + // archive, the first one is still present. + // If the archive does not exist, it is created. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_OPT_ADD_COMMENT : + // PCLZIP_OPT_PREPEND_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function add($p_filelist) + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_ADD_COMMENT => 'optional', + PCLZIP_OPT_PREPEND_COMMENT => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + //, PCLZIP_OPT_CRYPT => 'optional' + )); + if ($v_result != 1) { + return 0; + } + } - if ($v_size > 1) { - $v_arg_list = func_get_args(); + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { - array_shift($v_arg_list); - $v_size--; + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_ADD => 'optional', - PCLZIP_CB_POST_ADD => 'optional', - PCLZIP_OPT_NO_COMPRESSION => 'optional', - PCLZIP_OPT_COMMENT => 'optional', - PCLZIP_OPT_ADD_COMMENT => 'optional', - PCLZIP_OPT_PREPEND_COMMENT => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - )); - if ($v_result != 1) { - return 0; + // ----- Return + return 0; + } } } - else { - - $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); - if ($v_size == 2) { - $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; } - else if ($v_size > 2) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - - return 0; + + // ----- The list is a list of string names + else { + $v_string_list = $p_filelist; } } - } - $this->privOptionDefaultThreshold($v_options); + // ----- Look if the $p_filelist is a string + else if (is_string($p_filelist)) { + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); + } - $v_string_list = array(); - $v_att_list = array(); - $v_filedescr_list = array(); - $p_result_list = array(); - - if (is_array($p_filelist)) { - - if (isset($p_filelist[0]) && is_array($p_filelist[0])) { - $v_att_list = $p_filelist; + // ----- Invalid variable type for $p_filelist + else { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); + return 0; } - else { - $v_string_list = $p_filelist; + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } } - } - - else if (is_string($p_filelist)) { - $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); - } - - else { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); - return 0; - } - - if (sizeof($v_string_list) != 0) { - foreach ($v_string_list as $v_string) { - $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + + // ----- For each file in the list check the attributes + $v_supported_attributes + = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' + ,PCLZIP_ATT_FILE_MTIME => 'optional' + ,PCLZIP_ATT_FILE_CONTENT => 'optional' + ,PCLZIP_ATT_FILE_COMMENT => 'optional' + ); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, + $v_filedescr_list[], + $v_options, + $v_supported_attributes); + if ($v_result != 1) { + return 0; + } } - } - - $v_supported_attributes - = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' - ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' - ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' - ,PCLZIP_ATT_FILE_MTIME => 'optional' - ,PCLZIP_ATT_FILE_CONTENT => 'optional' - ,PCLZIP_ATT_FILE_COMMENT => 'optional' - ); - foreach ($v_att_list as $v_entry) { - $v_result = $this->privFileDescrParseAtt($v_entry, - $v_filedescr_list[], - $v_options, - $v_supported_attributes); + + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); if ($v_result != 1) { return 0; } - } - $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); - if ($v_result != 1) { - return 0; - } - - $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); - if ($v_result != 1) { - return 0; - } + // ----- Call the create fct + $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); + if ($v_result != 1) { + return 0; + } - return $p_result_list; -} + // ----- Return + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : listContent() + // Description : + // This public method, gives the list of the files and directories, with their + // properties. + // The properties of each entries in the list are (used also in other functions) : + // filename : Name of the file. For a create or add action it is the filename + // given by the user. For an extract function it is the filename + // of the extracted file. + // stored_filename : Name of the file / directory stored in the archive. + // size : Size of the stored file. + // compressed_size : Size of the file's data compressed in the archive + // (without the headers overhead) + // mtime : Last known modification date of the file (UNIX timestamp) + // comment : Comment associated with the file + // folder : true | false + // index : index of the file in the archive + // status : status of the action (depending of the action) : + // Values are : + // ok : OK ! + // filtered : the file / dir is not extracted (filtered by user) + // already_a_directory : the file can not be extracted because a + // directory with the same name already exists + // write_protected : the file can not be extracted because a file + // with the same name already exists and is + // write protected + // newer_exist : the file was not extracted because a newer file exists + // path_creation_fail : the file is not extracted because the folder + // does not exist and can not be created + // write_error : the file was not extracted because there was a + // error while writing the file + // read_error : the file was not extracted because there was a error + // while reading the file + // invalid_header : the file was not extracted because of an archive + // format error (bad file header) + // Note that each time a method can continue operating when there + // is an action error on a file, the error is only logged in the file status. + // Return Values : + // 0 on an unrecoverable failure, + // The list of the files in the archive. + // -------------------------------------------------------------------------------- + function listContent() + { + $v_result=1; -function listContent() -{ - $v_result=1; + // ----- Reset the error handler + $this->privErrorReset(); - $this->privErrorReset(); + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } - if (!$this->privCheckFormat()) { - return(0); - } + // ----- Call the extracting fct + $p_list = array(); + if (($v_result = $this->privList($p_list)) != 1) + { + unset($p_list); + return(0); + } - $p_list = array(); - if (($v_result = $this->privList($p_list)) != 1) + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // extract($p_path="./", $p_remove_path="") + // extract([$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method extract all the files / directories from the archive to the + // folder indicated in $p_path. + // If you want to ignore the 'root' part of path of the memorized files + // you can indicate this in the optional $p_remove_path parameter. + // By default, if a newer file with the same name already exists, the + // file is not extracted. + // + // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions + // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append + // at the end of the path value of PCLZIP_OPT_PATH. + // Parameters : + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 or a negative value on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function extract() { - unset($p_list); - return(0); - } - - return $p_list; -} - -function extract() -{ - $v_result=1; + $v_result=1; - $this->privErrorReset(); + // ----- Reset the error handler + $this->privErrorReset(); - if (!$this->privCheckFormat()) { - return(0); - } - - $v_options = array(); - $v_path = ''; - $v_remove_path = ""; - $v_remove_all_path = false; + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } - $v_size = func_num_args(); + // ----- Set default values + $v_options = array(); +// $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + + // ----- Look for arguments + if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional' + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + )); + if ($v_result != 1) { + return 0; + } - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + } - if ($v_size > 0) { - $v_arg_list = func_get_args(); + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + // ----- Get the first argument + $v_path = $v_arg_list[0]; - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_PATH => 'optional', - PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_EXTRACT => 'optional', - PCLZIP_CB_POST_EXTRACT => 'optional', - PCLZIP_OPT_SET_CHMOD => 'optional', - PCLZIP_OPT_BY_NAME => 'optional', - PCLZIP_OPT_BY_EREG => 'optional', - PCLZIP_OPT_BY_PREG => 'optional', - PCLZIP_OPT_BY_INDEX => 'optional', - PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', - PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', - PCLZIP_OPT_REPLACE_NEWER => 'optional' - ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' - ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - )); - if ($v_result != 1) { - return 0; - } + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - if (isset($v_options[PCLZIP_OPT_PATH])) { - $v_path = $v_options[PCLZIP_OPT_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { - $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { - $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; - } - if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { - if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { - $v_path .= '/'; + // ----- Return + return 0; } - $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; } } - else { - - $v_path = $v_arg_list[0]; + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); - if ($v_size == 2) { - $v_remove_path = $v_arg_list[1]; - } - else if ($v_size > 2) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + // ----- Trace - return 0; - } + // ----- Call the extracting fct + $p_list = array(); + $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, + $v_remove_all_path, $v_options); + if ($v_result < 1) { + unset($p_list); + return(0); } - } - $this->privOptionDefaultThreshold($v_options); + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + + // -------------------------------------------------------------------------------- + // Function : + // extractByIndex($p_index, $p_path="./", $p_remove_path="") + // extractByIndex($p_index, [$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method is doing a partial extract of the archive. + // The extracted files or folders are identified by their index in the + // archive (from 0 to n). + // Note that if the index identify a folder, only the folder entry is + // extracted, not all the files included in the archive. + // Parameters : + // $p_index : A single index (integer) or a string of indexes of files to + // extract. The form of the string is "0,4-6,8-12" with only numbers + // and '-' for range or ',' to separate ranges. No spaces or ';' + // are allowed. + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and + // not as files. + // The resulting content is in a new field 'content' in the file + // structure. + // This option must be used alone (any other options are ignored). + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + //function extractByIndex($p_index, options...) + function extractByIndex($p_index) + { + $v_result=1; + // ----- Reset the error handler + $this->privErrorReset(); - $p_list = array(); - $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, - $v_remove_all_path, $v_options); - if ($v_result < 1) { - unset($p_list); - return(0); - } + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } - return $p_list; -} + // ----- Set default values + $v_options = array(); +// $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional' + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + )); + if ($v_result != 1) { + return 0; + } + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + } + else { + } + } -function extractByIndex($p_index) -{ - $v_result=1; + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { - $this->privErrorReset(); + // ----- Get the first argument + $v_path = $v_arg_list[0]; - if (!$this->privCheckFormat()) { - return(0); - } + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); - $v_options = array(); - $v_path = ''; - $v_remove_path = ""; - $v_remove_all_path = false; + // ----- Return + return 0; + } + } + } - $v_size = func_num_args(); + // ----- Trace - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + // ----- Trick + // Here I want to reuse extractByRule(), so I need to parse the $p_index + // with privParseOptions() + $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); + $v_options_trick = array(); + $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, + array (PCLZIP_OPT_BY_INDEX => 'optional' )); + if ($v_result != 1) { + return 0; + } + $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; - if ($v_size > 1) { - $v_arg_list = func_get_args(); + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); - array_shift($v_arg_list); - $v_size--; + // ----- Call the extracting fct + if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { + return(0); + } - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // delete([$p_option, $p_option_value, ...]) + // Description : + // This method removes files from the archive. + // If no parameters are given, then all the archive is emptied. + // Parameters : + // None or optional arguments. + // Options : + // PCLZIP_OPT_BY_INDEX : + // PCLZIP_OPT_BY_NAME : + // PCLZIP_OPT_BY_EREG : + // PCLZIP_OPT_BY_PREG : + // Return Values : + // 0 on failure, + // The list of the files which are still present in the archive. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function delete() + { + $v_result=1; - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_PATH => 'optional', - PCLZIP_OPT_REMOVE_PATH => 'optional', - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', - PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', - PCLZIP_OPT_ADD_PATH => 'optional', - PCLZIP_CB_PRE_EXTRACT => 'optional', - PCLZIP_CB_POST_EXTRACT => 'optional', - PCLZIP_OPT_SET_CHMOD => 'optional', - PCLZIP_OPT_REPLACE_NEWER => 'optional' - ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' - ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', - PCLZIP_OPT_TEMP_FILE_ON => 'optional', - PCLZIP_OPT_TEMP_FILE_OFF => 'optional' - )); - if ($v_result != 1) { - return 0; - } + // ----- Reset the error handler + $this->privErrorReset(); - if (isset($v_options[PCLZIP_OPT_PATH])) { - $v_path = $v_options[PCLZIP_OPT_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { - $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; - } - if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { - $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; - } - if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { - if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { - $v_path .= '/'; - } - $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; - } - if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; - } - else { - } + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); } - else { + // ----- Set default values + $v_options = array(); - $v_path = $v_arg_list[0]; + // ----- Look for variable options arguments + $v_size = func_num_args(); - if ($v_size == 2) { - $v_remove_path = $v_arg_list[1]; - } - else if ($v_size > 2) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + // ----- Look for arguments + if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); - return 0; + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional' )); + if ($v_result != 1) { + return 0; } } - } - - - $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); - $v_options_trick = array(); - $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, - array (PCLZIP_OPT_BY_INDEX => 'optional' )); - if ($v_result != 1) { - return 0; - } - $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; - $this->privOptionDefaultThreshold($v_options); + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); - if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { + // ----- Call the delete fct + $v_list = array(); + if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { + $this->privSwapBackMagicQuotes(); + unset($v_list); return(0); - } - - return $p_list; -} - -function delete() -{ - $v_result=1; + } - $this->privErrorReset(); + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); - if (!$this->privCheckFormat()) { - return(0); + // ----- Return + return $v_list; } + // -------------------------------------------------------------------------------- - $v_options = array(); + // -------------------------------------------------------------------------------- + // Function : deleteByIndex() + // Description : + // ***** Deprecated ***** + // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. + // -------------------------------------------------------------------------------- + function deleteByIndex($p_index) + { + + $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : properties() + // Description : + // This method gives the properties of the archive. + // The properties are : + // nb : Number of files in the archive + // comment : Comment associated with the archive file + // status : not_exist, ok + // Parameters : + // None + // Return Values : + // 0 on failure, + // An array with the archive properties. + // -------------------------------------------------------------------------------- + function properties() + { - $v_size = func_num_args(); + // ----- Reset the error handler + $this->privErrorReset(); - if ($v_size > 0) { - $v_arg_list = func_get_args(); + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, - array (PCLZIP_OPT_BY_NAME => 'optional', - PCLZIP_OPT_BY_EREG => 'optional', - PCLZIP_OPT_BY_PREG => 'optional', - PCLZIP_OPT_BY_INDEX => 'optional' )); - if ($v_result != 1) { - return 0; + // ----- Check archive + if (!$this->privCheckFormat()) { + $this->privSwapBackMagicQuotes(); + return(0); } - } - $this->privDisableMagicQuotes(); + // ----- Default properties + $v_prop = array(); + $v_prop['comment'] = ''; + $v_prop['nb'] = 0; + $v_prop['status'] = 'not_exist'; - $v_list = array(); - if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { - $this->privSwapBackMagicQuotes(); - unset($v_list); - return(0); - } + // ----- Look if file exists + if (@is_file($this->zipname)) + { + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) + { + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); - $this->privSwapBackMagicQuotes(); + // ----- Return + return 0; + } - return $v_list; -} + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privSwapBackMagicQuotes(); + return 0; + } -function deleteByIndex($p_index) -{ - - $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); + // ----- Close the zip file + $this->privCloseFd(); - return $p_list; -} + // ----- Set the user attributes + $v_prop['comment'] = $v_central_dir['comment']; + $v_prop['nb'] = $v_central_dir['entries']; + $v_prop['status'] = 'ok'; + } -function properties() -{ + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); - $this->privErrorReset(); + // ----- Return + return $v_prop; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : duplicate() + // Description : + // This method creates an archive by copying the content of an other one. If + // the archive already exist, it is replaced by the new one without any warning. + // Parameters : + // $p_archive : The filename of a valid archive, or + // a valid PclZip object. + // Return Values : + // 1 on success. + // 0 or a negative value on error (error code). + // -------------------------------------------------------------------------------- + function duplicate($p_archive) + { + $v_result = 1; - $this->privDisableMagicQuotes(); + // ----- Reset the error handler + $this->privErrorReset(); - if (!$this->privCheckFormat()) { - $this->privSwapBackMagicQuotes(); - return(0); - } + // ----- Look if the $p_archive is a PclZip object + if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) + { - $v_prop = array(); - $v_prop['comment'] = ''; - $v_prop['nb'] = 0; - $v_prop['status'] = 'not_exist'; + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive->zipname); + } - if (@is_file($this->zipname)) - { - if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) + // ----- Look if the $p_archive is a string (so a filename) + else if (is_string($p_archive)) { - $this->privSwapBackMagicQuotes(); - - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); - return 0; + // ----- Check that $p_archive is a valid zip file + // TBC : Should also check the archive format + if (!is_file($p_archive)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); + $v_result = PCLZIP_ERR_MISSING_FILE; + } + else { + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive); + } } - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + // ----- Invalid variable + else { - $this->privSwapBackMagicQuotes(); - return 0; + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; } - $this->privCloseFd(); - - $v_prop['comment'] = $v_central_dir['comment']; - $v_prop['nb'] = $v_central_dir['entries']; - $v_prop['status'] = 'ok'; + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : merge() + // Description : + // This method merge the $p_archive_to_add archive at the end of the current + // one ($this). + // If the archive ($this) does not exist, the merge becomes a duplicate. + // If the $p_archive_to_add archive does not exist, the merge is a success. + // Parameters : + // $p_archive_to_add : It can be directly the filename of a valid zip archive, + // or a PclZip object archive. + // Return Values : + // 1 on success, + // 0 or negative values on error (see below). + // -------------------------------------------------------------------------------- + function merge($p_archive_to_add) + { + $v_result = 1; - $this->privSwapBackMagicQuotes(); - - return $v_prop; -} + // ----- Reset the error handler + $this->privErrorReset(); -function duplicate($p_archive) -{ - $v_result = 1; + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } - $this->privErrorReset(); + // ----- Look if the $p_archive_to_add is a PclZip object + if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) + { - if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) - { + // ----- Merge the archive + $v_result = $this->privMerge($p_archive_to_add); + } - $v_result = $this->privDuplicate($p_archive->zipname); - } + // ----- Look if the $p_archive_to_add is a string (so a filename) + else if (is_string($p_archive_to_add)) + { - else if (is_string($p_archive)) - { + // ----- Create a temporary archive + $v_object_archive = new PclZip($p_archive_to_add); - if (!is_file($p_archive)) { - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); - $v_result = PCLZIP_ERR_MISSING_FILE; + // ----- Merge the archive + $v_result = $this->privMerge($v_object_archive); } - else { - $v_result = $this->privDuplicate($p_archive); + + // ----- Invalid variable + else + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; } - } - else - { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); - $v_result = PCLZIP_ERR_INVALID_PARAMETER; + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - return $v_result; -} - -function merge($p_archive_to_add) -{ - $v_result = 1; - - $this->privErrorReset(); - if (!$this->privCheckFormat()) { - return(0); - } - if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) + // -------------------------------------------------------------------------------- + // Function : errorCode() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorCode() { - - $v_result = $this->privMerge($p_archive_to_add); + if (PCLZIP_ERROR_EXTERNAL == 1) { + return(PclErrorCode()); + } + else { + return($this->error_code); + } } + // -------------------------------------------------------------------------------- - else if (is_string($p_archive_to_add)) + // -------------------------------------------------------------------------------- + // Function : errorName() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorName($p_with_code=false) { + $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', + PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', + PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', + PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', + PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', + PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', + PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', + PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', + PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', + PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', + PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', + PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', + PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', + PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', + PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', + PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', + PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', + PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', + PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' + ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' + ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' + ); + + if (isset($v_name[$this->error_code])) { + $v_value = $v_name[$this->error_code]; + } + else { + $v_value = 'NoName'; + } - $v_object_archive = new PclZip($p_archive_to_add); - - $v_result = $this->privMerge($v_object_archive); + if ($p_with_code) { + return($v_value.' ('.$this->error_code.')'); + } + else { + return($v_value); + } } + // -------------------------------------------------------------------------------- - else + // -------------------------------------------------------------------------------- + // Function : errorInfo() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorInfo($p_full=false) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); - $v_result = PCLZIP_ERR_INVALID_PARAMETER; - } - - return $v_result; -} - - - -function errorCode() -{ - if (PCLZIP_ERROR_EXTERNAL == 1) { - return(PclErrorCode()); - } - else { - return($this->error_code); - } -} - -function errorName($p_with_code=false) -{ - $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', - PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', - PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', - PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', - PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', - PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', - PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', - PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', - PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', - PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', - PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', - PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', - PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', - PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', - PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', - PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', - PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', - PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', - PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' - ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' - ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' - ); - - if (isset($v_name[$this->error_code])) { - $v_value = $v_name[$this->error_code]; - } - else { - $v_value = 'NoName'; - } - - if ($p_with_code) { - return($v_value.' ('.$this->error_code.')'); - } - else { - return($v_value); - } -} - -function errorInfo($p_full=false) -{ - if (PCLZIP_ERROR_EXTERNAL == 1) { - return(PclErrorString()); - } - else { - if ($p_full) { - return($this->errorName(true)." : ".$this->error_string); + if (PCLZIP_ERROR_EXTERNAL == 1) { + return(PclErrorString()); } else { - return($this->error_string." [code ".$this->error_code."]"); + if ($p_full) { + return($this->errorName(true)." : ".$this->error_string); + } + else { + return($this->error_string." [code ".$this->error_code."]"); + } } } -} - - - - - -function privCheckFormat($p_level=0) -{ - $v_result = true; - - clearstatcache(); - - $this->privErrorReset(); - - if (!is_file($this->zipname)) { - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); - return(false); - } + // -------------------------------------------------------------------------------- - if (!is_readable($this->zipname)) { - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); - return(false); - } +// -------------------------------------------------------------------------------- +// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** +// ***** ***** +// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** +// -------------------------------------------------------------------------------- - return $v_result; -} + // -------------------------------------------------------------------------------- + // Function : privCheckFormat() + // Description : + // This method check that the archive exists and is a valid zip archive. + // Several level of check exists. (futur) + // Parameters : + // $p_level : Level of check. Default 0. + // 0 : Check the first bytes (magic codes) (default value)) + // 1 : 0 + Check the central directory (futur) + // 2 : 1 + Check each file header (futur) + // Return Values : + // true on success, + // false on error, the error code is set. + // -------------------------------------------------------------------------------- + function privCheckFormat($p_level=0) + { + $v_result = true; -function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) -{ - $v_result=1; - - $i=0; - while ($i<$p_size) { + // ----- Reset the file system cache + clearstatcache(); - if (!isset($v_requested_options[$p_options_list[$i]])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); + // ----- Reset the error handler + $this->privErrorReset(); - return PclZip::errorCode(); + // ----- Look if the file exits + if (!is_file($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); + return(false); } - switch ($p_options_list[$i]) { - case PCLZIP_OPT_PATH : - case PCLZIP_OPT_REMOVE_PATH : - case PCLZIP_OPT_ADD_PATH : - if (($i+1) >= $p_size) { - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Check that the file is readeable + if (!is_readable($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); + return(false); + } - return PclZip::errorCode(); - } + // ----- Check the magic code + // TBC - $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); - $i++; - break; + // ----- Check the central header + // TBC - case PCLZIP_OPT_TEMP_FILE_THRESHOLD : - if (($i+1) >= $p_size) { - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - return PclZip::errorCode(); - } - - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); - return PclZip::errorCode(); - } - - $v_value = $p_options_list[$i+1]; - if ((!is_integer($v_value)) || ($v_value<0)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - return PclZip::errorCode(); - } - - $v_result_list[$p_options_list[$i]] = $v_value*1048576; - $i++; - break; + // ----- Check each file header + // TBC - case PCLZIP_OPT_TEMP_FILE_ON : - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); - return PclZip::errorCode(); - } - - $v_result_list[$p_options_list[$i]] = true; - break; + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privParseOptions() + // Description : + // This internal methods reads the variable list of arguments ($p_options_list, + // $p_size) and generate an array with the options and values ($v_result_list). + // $v_requested_options contains the options that can be present and those that + // must be present. + // $v_requested_options is an array, with the option value as key, and 'optional', + // or 'mandatory' as value. + // Parameters : + // See above. + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) + { + $v_result=1; + + // ----- Read the options + $i=0; + while ($i<$p_size) { - case PCLZIP_OPT_TEMP_FILE_OFF : - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"); - return PclZip::errorCode(); - } - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"); - return PclZip::errorCode(); - } - - $v_result_list[$p_options_list[$i]] = true; - break; + // ----- Check if the option is supported + if (!isset($v_requested_options[$p_options_list[$i]])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); - case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : - if (($i+1) >= $p_size) { - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Return + return PclZip::errorCode(); + } - return PclZip::errorCode(); - } + // ----- Look for next option + switch ($p_options_list[$i]) { + // ----- Look for options that request a path value + case PCLZIP_OPT_PATH : + case PCLZIP_OPT_REMOVE_PATH : + case PCLZIP_OPT_ADD_PATH : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } - if ( is_string($p_options_list[$i+1]) - && ($p_options_list[$i+1] != '')) { + // ----- Get the value $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); $i++; - } - else { - } - break; + break; - case PCLZIP_OPT_BY_NAME : - if (($i+1) >= $p_size) { - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + case PCLZIP_OPT_TEMP_FILE_THRESHOLD : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + return PclZip::errorCode(); + } + + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); + return PclZip::errorCode(); + } + + // ----- Check the value + $v_value = $p_options_list[$i+1]; + if ((!is_integer($v_value)) || ($v_value<0)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + return PclZip::errorCode(); + } - return PclZip::errorCode(); - } + // ----- Get the value (and convert it in bytes) + $v_result_list[$p_options_list[$i]] = $v_value*1048576; + $i++; + break; - if (is_string($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; - } - else if (is_array($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; - } - else { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + case PCLZIP_OPT_TEMP_FILE_ON : + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); + return PclZip::errorCode(); + } + + $v_result_list[$p_options_list[$i]] = true; + break; - return PclZip::errorCode(); - } - $i++; - break; + case PCLZIP_OPT_TEMP_FILE_OFF : + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"); + return PclZip::errorCode(); + } + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"); + return PclZip::errorCode(); + } + + $v_result_list[$p_options_list[$i]] = true; + break; - case PCLZIP_OPT_BY_EREG : - $p_options_list[$i] = PCLZIP_OPT_BY_PREG; - case PCLZIP_OPT_BY_PREG : - if (($i+1) >= $p_size) { - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - return PclZip::errorCode(); - } + // ----- Return + return PclZip::errorCode(); + } - if (is_string($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; - } - else { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Get the value + if ( is_string($p_options_list[$i+1]) + && ($p_options_list[$i+1] != '')) { + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); + $i++; + } + else { + } + break; - return PclZip::errorCode(); - } - $i++; - break; + // ----- Look for options that request an array of string for value + case PCLZIP_OPT_BY_NAME : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - case PCLZIP_OPT_COMMENT : - case PCLZIP_OPT_ADD_COMMENT : - case PCLZIP_OPT_PREPEND_COMMENT : - if (($i+1) >= $p_size) { - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, - "Missing parameter value for option '" - .PclZipUtilOptionText($p_options_list[$i]) - ."'"); + // ----- Return + return PclZip::errorCode(); + } - return PclZip::errorCode(); - } + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; + } + else if (is_array($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - if (is_string($p_options_list[$i+1])) { - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; - } - else { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, - "Wrong parameter value for option '" - .PclZipUtilOptionText($p_options_list[$i]) - ."'"); + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; - return PclZip::errorCode(); - } - $i++; - break; + // ----- Look for options that request an EREG or PREG expression + case PCLZIP_OPT_BY_EREG : + // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG + // to PCLZIP_OPT_BY_PREG + $p_options_list[$i] = PCLZIP_OPT_BY_PREG; + case PCLZIP_OPT_BY_PREG : + //case PCLZIP_OPT_CRYPT : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } - case PCLZIP_OPT_BY_INDEX : - if (($i+1) >= $p_size) { - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - return PclZip::errorCode(); - } + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; - $v_work_list = array(); - if (is_string($p_options_list[$i+1])) { + // ----- Look for options that takes a string + case PCLZIP_OPT_COMMENT : + case PCLZIP_OPT_ADD_COMMENT : + case PCLZIP_OPT_PREPEND_COMMENT : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, + "Missing parameter value for option '" + .PclZipUtilOptionText($p_options_list[$i]) + ."'"); + + // ----- Return + return PclZip::errorCode(); + } - $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', ''); + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, + "Wrong parameter value for option '" + .PclZipUtilOptionText($p_options_list[$i]) + ."'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; - $v_work_list = explode(",", $p_options_list[$i+1]); - } - else if (is_integer($p_options_list[$i+1])) { - $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1]; - } - else if (is_array($p_options_list[$i+1])) { - $v_work_list = $p_options_list[$i+1]; - } - else { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Look for options that request an array of index + case PCLZIP_OPT_BY_INDEX : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - return PclZip::errorCode(); - } - - $v_sort_flag=false; - $v_sort_value=0; - for ($j=0; $j= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - case PCLZIP_OPT_SET_CHMOD : - if (($i+1) >= $p_size) { - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Return + return PclZip::errorCode(); + } - return PclZip::errorCode(); - } + // ----- Get the value + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + $i++; + break; - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; - $i++; - break; - - case PCLZIP_CB_PRE_EXTRACT : - case PCLZIP_CB_POST_EXTRACT : - case PCLZIP_CB_PRE_ADD : - case PCLZIP_CB_POST_ADD : - /* for futur use - case PCLZIP_CB_PRE_DELETE : - case PCLZIP_CB_POST_DELETE : - case PCLZIP_CB_PRE_LIST : - case PCLZIP_CB_POST_LIST : - */ - if (($i+1) >= $p_size) { - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Look for options that request a call-back + case PCLZIP_CB_PRE_EXTRACT : + case PCLZIP_CB_POST_EXTRACT : + case PCLZIP_CB_PRE_ADD : + case PCLZIP_CB_POST_ADD : + /* for futur use + case PCLZIP_CB_PRE_DELETE : + case PCLZIP_CB_POST_DELETE : + case PCLZIP_CB_PRE_LIST : + case PCLZIP_CB_POST_LIST : + */ + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } - return PclZip::errorCode(); - } + // ----- Get the value + $v_function_name = $p_options_list[$i+1]; - $v_function_name = $p_options_list[$i+1]; + // ----- Check that the value is a valid existing function + if (!function_exists($v_function_name)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'"); - if (!function_exists($v_function_name)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + // ----- Return + return PclZip::errorCode(); + } - return PclZip::errorCode(); - } + // ----- Set the attribute + $v_result_list[$p_options_list[$i]] = $v_function_name; + $i++; + break; - $v_result_list[$p_options_list[$i]] = $v_function_name; - $i++; - break; + default : + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Unknown parameter '" + .$p_options_list[$i]."'"); - default : - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, - "Unknown parameter '" - .$p_options_list[$i]."'"); + // ----- Return + return PclZip::errorCode(); + } - return PclZip::errorCode(); + // ----- Next options + $i++; } - $i++; - } - - if ($v_requested_options !== false) { - for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { - if ($v_requested_options[$key] == 'mandatory') { - if (!isset($v_result_list[$key])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); + // ----- Look for mandatory options + if ($v_requested_options !== false) { + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { + // ----- Look for mandatory option + if ($v_requested_options[$key] == 'mandatory') { + // ----- Look if present + if (!isset($v_result_list[$key])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); - return PclZip::errorCode(); + // ----- Return + return PclZip::errorCode(); + } } } } - } - - if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { - } - - return $v_result; -} + // ----- Look for default values + if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { + + } -function privOptionDefaultThreshold(&$p_options) -{ - $v_result=1; - - if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) - || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) { + // ----- Return return $v_result; } - - $v_memory_limit = ini_get('memory_limit'); - $v_memory_limit = trim($v_memory_limit); - $last = strtolower(substr($v_memory_limit, -1)); - - if($last == 'g') - $v_memory_limit = $v_memory_limit*1073741824; - if($last == 'm') - $v_memory_limit = $v_memory_limit*1048576; - if($last == 'k') - $v_memory_limit = $v_memory_limit*1024; - - $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO); - - - if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) { - unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]); - } - - return $v_result; -} + // -------------------------------------------------------------------------------- -function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false) -{ - $v_result=1; - - foreach ($p_file_list as $v_key => $v_value) { - - if (!isset($v_requested_options[$v_key])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file"); + // -------------------------------------------------------------------------------- + // Function : privOptionDefaultThreshold() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privOptionDefaultThreshold(&$p_options) + { + $v_result=1; + + if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) { + return $v_result; + } + + // ----- Get 'memory_limit' configuration value + $v_memory_limit = ini_get('memory_limit'); + $v_memory_limit = trim($v_memory_limit); + $last = strtolower(substr($v_memory_limit, -1)); + + if($last == 'g') + //$v_memory_limit = $v_memory_limit*1024*1024*1024; + $v_memory_limit = $v_memory_limit*1073741824; + if($last == 'm') + //$v_memory_limit = $v_memory_limit*1024*1024; + $v_memory_limit = $v_memory_limit*1048576; + if($last == 'k') + $v_memory_limit = $v_memory_limit*1024; + + $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO); + - return PclZip::errorCode(); + // ----- Sanity check : No threshold if value lower than 1M + if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) { + unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]); } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privFileDescrParseAtt() + // Description : + // Parameters : + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false) + { + $v_result=1; + + // ----- For each file in the list check the attributes + foreach ($p_file_list as $v_key => $v_value) { + + // ----- Check if the option is supported + if (!isset($v_requested_options[$v_key])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file"); - switch ($v_key) { - case PCLZIP_ATT_FILE_NAME : - if (!is_string($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } + // ----- Return + return PclZip::errorCode(); + } - $p_filedescr['filename'] = PclZipUtilPathReduction($v_value); - - if ($p_filedescr['filename'] == '') { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } + // ----- Look for attribute + switch ($v_key) { + case PCLZIP_ATT_FILE_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } - break; + $p_filedescr['filename'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['filename'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } - case PCLZIP_ATT_FILE_NEW_SHORT_NAME : - if (!is_string($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } + break; - $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value); + case PCLZIP_ATT_FILE_NEW_SHORT_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } - if ($p_filedescr['new_short_name'] == '') { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - break; + $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value); - case PCLZIP_ATT_FILE_NEW_FULL_NAME : - if (!is_string($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } + if ($p_filedescr['new_short_name'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + break; - $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value); + case PCLZIP_ATT_FILE_NEW_FULL_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } - if ($p_filedescr['new_full_name'] == '') { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } - break; + $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value); - case PCLZIP_ATT_FILE_COMMENT : - if (!is_string($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } + if ($p_filedescr['new_full_name'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + break; - $p_filedescr['comment'] = $v_value; - break; + // ----- Look for options that takes a string + case PCLZIP_ATT_FILE_COMMENT : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } - case PCLZIP_ATT_FILE_MTIME : - if (!is_integer($v_value)) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'"); - return PclZip::errorCode(); - } + $p_filedescr['comment'] = $v_value; + break; - $p_filedescr['mtime'] = $v_value; - break; + case PCLZIP_ATT_FILE_MTIME : + if (!is_integer($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } - case PCLZIP_ATT_FILE_CONTENT : - $p_filedescr['content'] = $v_value; - break; + $p_filedescr['mtime'] = $v_value; + break; - default : - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, - "Unknown parameter '".$v_key."'"); + case PCLZIP_ATT_FILE_CONTENT : + $p_filedescr['content'] = $v_value; + break; - return PclZip::errorCode(); - } + default : + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Unknown parameter '".$v_key."'"); - if ($v_requested_options !== false) { - for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { - if ($v_requested_options[$key] == 'mandatory') { - if (!isset($p_file_list[$key])) { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); - return PclZip::errorCode(); + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for mandatory options + if ($v_requested_options !== false) { + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { + // ----- Look for mandatory option + if ($v_requested_options[$key] == 'mandatory') { + // ----- Look if present + if (!isset($p_file_list[$key])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); + return PclZip::errorCode(); + } } } } + + // end foreach } - - } - - return $v_result; -} - -function privFileDescrExpand(&$p_filedescr_list, &$p_options) -{ - $v_result=1; - - $v_result_list = array(); - - for ($i=0; $iprivCalculateStoredFilename($v_descr, $p_options); - - $v_result_list[sizeof($v_result_list)] = $v_descr; - - if ($v_descr['type'] == 'folder') { - $v_dirlist_descr = array(); - $v_dirlist_nb = 0; - if ($v_folder_handler = @opendir($v_descr['filename'])) { - while (($v_item_handler = @readdir($v_folder_handler)) !== false) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist"); - if (($v_item_handler == '.') || ($v_item_handler == '..')) { - continue; - } - - $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler; - - if ($v_descr['stored_filename'] != $v_descr['filename']) { - if ($v_descr['stored_filename'] != '') { - $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler; + // ----- Return + return PclZip::errorCode(); + } + + // ----- Calculate the stored filename + $this->privCalculateStoredFilename($v_descr, $p_options); + + // ----- Add the descriptor in result list + $v_result_list[sizeof($v_result_list)] = $v_descr; + + // ----- Look for folder + if ($v_descr['type'] == 'folder') { + // ----- List of items in folder + $v_dirlist_descr = array(); + $v_dirlist_nb = 0; + if ($v_folder_handler = @opendir($v_descr['filename'])) { + while (($v_item_handler = @readdir($v_folder_handler)) !== false) { + + // ----- Skip '.' and '..' + if (($v_item_handler == '.') || ($v_item_handler == '..')) { + continue; } - else { - $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler; + + // ----- Compose the full filename + $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler; + + // ----- Look for different stored filename + // Because the name of the folder was changed, the name of the + // files/sub-folders also change + if (($v_descr['stored_filename'] != $v_descr['filename']) + && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) { + if ($v_descr['stored_filename'] != '') { + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler; + } + else { + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler; + } } + + $v_dirlist_nb++; } - - $v_dirlist_nb++; + + @closedir($v_folder_handler); } - - @closedir($v_folder_handler); - } - else { - } - - if ($v_dirlist_nb != 0) { - if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) { - return $v_result; + else { + // TBC : unable to open folder in read mode } - $v_result_list = array_merge($v_result_list, $v_dirlist_descr); - } - else { + // ----- Expand each element of the list + if ($v_dirlist_nb != 0) { + // ----- Expand + if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) { + return $v_result; + } + + // ----- Concat the resulting list + $v_result_list = array_merge($v_result_list, $v_dirlist_descr); + } + else { + } + + // ----- Free local array + unset($v_dirlist_descr); } - - unset($v_dirlist_descr); } - } - - $p_filedescr_list = $v_result_list; - - return $v_result; -} - -function privCreate($p_filedescr_list, &$p_result_list, &$p_options) -{ - $v_result=1; - $v_list_detail = array(); - - $this->privDisableMagicQuotes(); - - if (($v_result = $this->privOpenFd('wb')) != 1) - { - return $v_result; - } - - $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options); - - $this->privCloseFd(); - - $this->privSwapBackMagicQuotes(); - - return $v_result; -} - -function privAdd($p_filedescr_list, &$p_result_list, &$p_options) -{ - $v_result=1; - $v_list_detail = array(); - - if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) - { - - $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); - - return $v_result; - } - $this->privDisableMagicQuotes(); - - if (($v_result=$this->privOpenFd('rb')) != 1) - { - $this->privSwapBackMagicQuotes(); - - return $v_result; - } - - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result; - } - - @rewind($this->zip_fd); - - $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; - - if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) - { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); - - return PclZip::errorCode(); - } - - $v_size = $v_central_dir['offset']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = fread($this->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - - $v_swap = $this->zip_fd; - $this->zip_fd = $v_zip_temp_fd; - $v_zip_temp_fd = $v_swap; - - $v_header_list = array(); - if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) - { - fclose($v_zip_temp_fd); - $this->privCloseFd(); - @unlink($v_zip_temp_name); - $this->privSwapBackMagicQuotes(); + + // ----- Get the result list + $p_filedescr_list = $v_result_list; + // ----- Return return $v_result; } + // -------------------------------------------------------------------------------- - $v_offset = @ftell($this->zip_fd); - - $v_size = $v_central_dir['size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($v_zip_temp_fd, $v_read_size); - @fwrite($this->zip_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - - for ($i=0, $v_count=0; $iprivWriteCentralFileHeader($v_header_list[$i])) != 1) { - fclose($v_zip_temp_fd); - $this->privCloseFd(); - @unlink($v_zip_temp_name); - $this->privSwapBackMagicQuotes(); - - return $v_result; - } - $v_count++; - } - - $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); - } - - $v_comment = $v_central_dir['comment']; - if (isset($p_options[PCLZIP_OPT_COMMENT])) { - $v_comment = $p_options[PCLZIP_OPT_COMMENT]; - } - if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) { - $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT]; - } - if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) { - $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment; - } - - $v_size = @ftell($this->zip_fd)-$v_offset; - - if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) + // -------------------------------------------------------------------------------- + // Function : privCreate() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privCreate($p_filedescr_list, &$p_result_list, &$p_options) { - unset($v_header_list); - $this->privSwapBackMagicQuotes(); - - return $v_result; - } - - $v_swap = $this->zip_fd; - $this->zip_fd = $v_zip_temp_fd; - $v_zip_temp_fd = $v_swap; - - $this->privCloseFd(); - - @fclose($v_zip_temp_fd); + $v_result=1; + $v_list_detail = array(); + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); - $this->privSwapBackMagicQuotes(); + // ----- Open the file in write mode + if (($v_result = $this->privOpenFd('wb')) != 1) + { + // ----- Return + return $v_result; + } - @unlink($this->zipname); + // ----- Add the list of files + $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options); - PclZipUtilRename($v_zip_temp_name, $this->zipname); + // ----- Close + $this->privCloseFd(); - return $v_result; -} + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); -function privOpenFd($p_mode) -{ - $v_result=1; + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- - if ($this->zip_fd != 0) + // -------------------------------------------------------------------------------- + // Function : privAdd() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAdd($p_filedescr_list, &$p_result_list, &$p_options) { - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open'); + $v_result=1; + $v_list_detail = array(); - return PclZip::errorCode(); - } + // ----- Look if the archive exists or is empty + if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) + { - if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) - { - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode'); + // ----- Do a create + $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); - return PclZip::errorCode(); - } + // ----- Return + return $v_result; + } + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); - return $v_result; -} + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); -function privCloseFd() -{ - $v_result=1; + // ----- Return + return $v_result; + } - if ($this->zip_fd != 0) - @fclose($this->zip_fd); - $this->zip_fd = 0; + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } - return $v_result; -} + // ----- Go to beginning of File + @rewind($this->zip_fd); -function privAddList($p_filedescr_list, &$p_result_list, &$p_options) -{ - $v_result=1; + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; - $v_header_list = array(); - if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) - { - return $v_result; - } + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) + { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); - $v_offset = @ftell($this->zip_fd); + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); - for ($i=0,$v_count=0; $iprivWriteCentralFileHeader($v_header_list[$i])) != 1) { - return $v_result; - } - $v_count++; + // ----- Return + return PclZip::errorCode(); } - $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); - } - - $v_comment = ''; - if (isset($p_options[PCLZIP_OPT_COMMENT])) { - $v_comment = $p_options[PCLZIP_OPT_COMMENT]; - } + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } - $v_size = @ftell($this->zip_fd)-$v_offset; + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; - if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) - { - unset($v_header_list); + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) + { + fclose($v_zip_temp_fd); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + $this->privSwapBackMagicQuotes(); - return $v_result; - } + // ----- Return + return $v_result; + } - return $v_result; -} + // ----- Store the offset of the central dir + $v_offset = @ftell($this->zip_fd); -function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) -{ - $v_result=1; - $v_header = array(); + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } - $v_nb = sizeof($p_result_list); + // ----- Create the Central Dir files header + for ($i=0, $v_count=0; $iprivWriteCentralFileHeader($v_header_list[$i])) != 1) { + fclose($v_zip_temp_fd); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + $this->privSwapBackMagicQuotes(); - for ($j=0; ($jprivConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); } - if ( ($p_filedescr_list[$j]['type'] != 'virtual_file') - && (!file_exists($p_filedescr_list[$j]['filename']))) { - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist"); - return PclZip::errorCode(); + // ----- Zip file comment + $v_comment = $v_central_dir['comment']; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) { + $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT]; + } + if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment; } - if ( ($p_filedescr_list[$j]['type'] == 'file') - || ($p_filedescr_list[$j]['type'] == 'virtual_file') - || ( ($p_filedescr_list[$j]['type'] == 'folder') - && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]) - || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) - ) { + // ----- Calculate the size of the central header + $v_size = @ftell($this->zip_fd)-$v_offset; - $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header, - $p_options); - if ($v_result != 1) { - return $v_result; - } + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) + { + // ----- Reset the file list + unset($v_header_list); + $this->privSwapBackMagicQuotes(); - $p_result_list[$v_nb++] = $v_header; + // ----- Return + return $v_result; } - } - return $v_result; -} + // ----- Swap back the file descriptor + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; -function privAddFile($p_filedescr, &$p_header, &$p_options) -{ - $v_result=1; - - $p_filename = $p_filedescr['filename']; - - if ($p_filename == "") { - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); + // ----- Close + $this->privCloseFd(); - return PclZip::errorCode(); - } + // ----- Close the temporary file + @fclose($v_zip_temp_fd); - /* TBC : Removed - if (isset($p_filedescr['stored_filename'])) { - $v_stored_filename = $p_filedescr['stored_filename']; - } - else { - $v_stored_filename = $p_filedescr['stored_filename']; - } - */ + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); - clearstatcache(); - $p_header['version'] = 20; - $p_header['version_extracted'] = 10; - $p_header['flag'] = 0; - $p_header['compression'] = 0; - $p_header['crc'] = 0; - $p_header['compressed_size'] = 0; - $p_header['filename_len'] = strlen($p_filename); - $p_header['extra_len'] = 0; - $p_header['disk'] = 0; - $p_header['internal'] = 0; - $p_header['offset'] = 0; - $p_header['filename'] = $p_filename; - $p_header['stored_filename'] = $p_filedescr['stored_filename']; - $p_header['extra'] = ''; - $p_header['status'] = 'ok'; - $p_header['index'] = -1; - - if ($p_filedescr['type']=='file') { - $p_header['external'] = 0x00000000; - $p_header['size'] = filesize($p_filename); - } - - else if ($p_filedescr['type']=='folder') { - $p_header['external'] = 0x00000010; - $p_header['mtime'] = filemtime($p_filename); - $p_header['size'] = filesize($p_filename); - } - - else if ($p_filedescr['type'] == 'virtual_file') { - $p_header['external'] = 0x00000000; - $p_header['size'] = strlen($p_filedescr['content']); - } - + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); - if (isset($p_filedescr['mtime'])) { - $p_header['mtime'] = $p_filedescr['mtime']; - } - else if ($p_filedescr['type'] == 'virtual_file') { - $p_header['mtime'] = time(); - } - else { - $p_header['mtime'] = filemtime($p_filename); - } + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); - if (isset($p_filedescr['comment'])) { - $p_header['comment_len'] = strlen($p_filedescr['comment']); - $p_header['comment'] = $p_filedescr['comment']; - } - else { - $p_header['comment_len'] = 0; - $p_header['comment'] = ''; + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - if (isset($p_options[PCLZIP_CB_PRE_ADD])) { + // -------------------------------------------------------------------------------- + // Function : privOpenFd() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privOpenFd($p_mode) + { + $v_result=1; - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_header, $v_local_header); + // ----- Look if already open + if ($this->zip_fd != 0) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open'); - eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);'); - if ($v_result == 0) { - $p_header['status'] = "skipped"; - $v_result = 1; + // ----- Return + return PclZip::errorCode(); } - if ($p_header['stored_filename'] != $v_local_header['stored_filename']) { - $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']); + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode'); + + // ----- Return + return PclZip::errorCode(); } - } - if ($p_header['stored_filename'] == "") { - $p_header['status'] = "filtered"; - } - - if (strlen($p_header['stored_filename']) > 0xFF) { - $p_header['status'] = 'filename_too_long'; + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - if ($p_header['status'] == 'ok') { + // -------------------------------------------------------------------------------- + // Function : privCloseFd() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privCloseFd() + { + $v_result=1; - if ($p_filedescr['type'] == 'file') { - if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) - && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) - || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) - && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) { - $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options); - if ($v_result < PCLZIP_ERR_NO_ERROR) { - return $v_result; - } - } - - else { + if ($this->zip_fd != 0) + @fclose($this->zip_fd); + $this->zip_fd = 0; - if (($v_file = @fopen($p_filename, "rb")) == 0) { - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); - return PclZip::errorCode(); - } + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddList() + // Description : + // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is + // different from the real path of the file. This is usefull if you want to have PclTar + // running in any directory, and memorize relative path from an other directory. + // Parameters : + // $p_list : An array containing the file or directory names to add in the tar + // $p_result_list : list of added files with their properties (specially the status field) + // $p_add_dir : Path to add in the filename path archived + // $p_remove_dir : Path to remove in the filename path archived + // Return Values : + // -------------------------------------------------------------------------------- +// function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options) + function privAddList($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; - $v_content = @fread($v_file, $p_header['size']); + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) + { + // ----- Return + return $v_result; + } - @fclose($v_file); + // ----- Store the offset of the central dir + $v_offset = @ftell($this->zip_fd); - $p_header['crc'] = @crc32($v_content); - - if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { - $p_header['compressed_size'] = $p_header['size']; - $p_header['compression'] = 0; + // ----- Create the Central Dir files header + for ($i=0,$v_count=0; $iprivWriteCentralFileHeader($v_header_list[$i])) != 1) { + // ----- Return + return $v_result; + } + $v_count++; } - - else { - $v_content = @gzdeflate($v_content); - $p_header['compressed_size'] = strlen($v_content); - $p_header['compression'] = 8; - } - - if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { - @fclose($v_file); - return $v_result; - } + // ----- Transform the header to a 'usable' info + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + // ----- Zip file comment + $v_comment = ''; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } - @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); + // ----- Calculate the size of the central header + $v_size = @ftell($this->zip_fd)-$v_offset; - } + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) + { + // ----- Reset the file list + unset($v_header_list); + // ----- Return + return $v_result; } - else if ($p_filedescr['type'] == 'virtual_file') { - - $v_content = $p_filedescr['content']; + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFileList() + // Description : + // Parameters : + // $p_filedescr_list : An array containing the file description + // or directory names to add in the zip + // $p_result_list : list of added files with their properties (specially the status field) + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + $v_header = array(); - $p_header['crc'] = @crc32($v_content); - - if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { - $p_header['compressed_size'] = $p_header['size']; - $p_header['compression'] = 0; - } - - else { - $v_content = @gzdeflate($v_content); + // ----- Recuperate the current number of elt in list + $v_nb = sizeof($p_result_list); - $p_header['compressed_size'] = strlen($v_content); - $p_header['compression'] = 8; - } + // ----- Loop on the files + for ($j=0; ($jprivWriteFileHeader($p_header)) != 1) { - @fclose($v_file); - return $v_result; - } - @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); - } + // ----- Skip empty file names + // TBC : Can this be possible ? not checked in DescrParseAtt ? + if ($p_filedescr_list[$j]['filename'] == "") { + continue; + } - else if ($p_filedescr['type'] == 'folder') { - if (@substr($p_header['stored_filename'], -1) != '/') { - $p_header['stored_filename'] .= '/'; + // ----- Check the filename + if ( ($p_filedescr_list[$j]['type'] != 'virtual_file') + && (!file_exists($p_filedescr_list[$j]['filename']))) { + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist"); + return PclZip::errorCode(); } - $p_header['size'] = 0; + // ----- Look if it is a file or a dir with no all path remove option + // or a dir with all its path removed +// if ( (is_file($p_filedescr_list[$j]['filename'])) +// || ( is_dir($p_filedescr_list[$j]['filename']) + if ( ($p_filedescr_list[$j]['type'] == 'file') + || ($p_filedescr_list[$j]['type'] == 'virtual_file') + || ( ($p_filedescr_list[$j]['type'] == 'folder') + && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]) + || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) + ) { + + // ----- Add the file + $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header, + $p_options); + if ($v_result != 1) { + return $v_result; + } - if (($v_result = $this->privWriteFileHeader($p_header)) != 1) - { - return $v_result; + // ----- Store the file infos + $p_result_list[$v_nb++] = $v_header; } } + + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - if (isset($p_options[PCLZIP_CB_POST_ADD])) { + // -------------------------------------------------------------------------------- + // Function : privAddFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFile($p_filedescr, &$p_header, &$p_options) + { + $v_result=1; + + // ----- Working variable + $p_filename = $p_filedescr['filename']; - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_header, $v_local_header); + // TBC : Already done in the fileAtt check ... ? + if ($p_filename == "") { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); - eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);'); - if ($v_result == 0) { - $v_result = 1; + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for a stored different filename + /* TBC : Removed + if (isset($p_filedescr['stored_filename'])) { + $v_stored_filename = $p_filedescr['stored_filename']; + } + else { + $v_stored_filename = $p_filedescr['stored_filename']; } + */ + + // ----- Set the file properties + clearstatcache(); + $p_header['version'] = 20; + $p_header['version_extracted'] = 10; + $p_header['flag'] = 0; + $p_header['compression'] = 0; + $p_header['crc'] = 0; + $p_header['compressed_size'] = 0; + $p_header['filename_len'] = strlen($p_filename); + $p_header['extra_len'] = 0; + $p_header['disk'] = 0; + $p_header['internal'] = 0; + $p_header['offset'] = 0; + $p_header['filename'] = $p_filename; +// TBC : Removed $p_header['stored_filename'] = $v_stored_filename; + $p_header['stored_filename'] = $p_filedescr['stored_filename']; + $p_header['extra'] = ''; + $p_header['status'] = 'ok'; + $p_header['index'] = -1; - } + // ----- Look for regular file + if ($p_filedescr['type']=='file') { + $p_header['external'] = 0x00000000; + $p_header['size'] = filesize($p_filename); + } + + // ----- Look for regular folder + else if ($p_filedescr['type']=='folder') { + $p_header['external'] = 0x00000010; + $p_header['mtime'] = filemtime($p_filename); + $p_header['size'] = filesize($p_filename); + } + + // ----- Look for virtual file + else if ($p_filedescr['type'] == 'virtual_file') { + $p_header['external'] = 0x00000000; + $p_header['size'] = strlen($p_filedescr['content']); + } + - return $v_result; -} + // ----- Look for filetime + if (isset($p_filedescr['mtime'])) { + $p_header['mtime'] = $p_filedescr['mtime']; + } + else if ($p_filedescr['type'] == 'virtual_file') { + $p_header['mtime'] = time(); + } + else { + $p_header['mtime'] = filemtime($p_filename); + } -function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options) -{ - $v_result=PCLZIP_ERR_NO_ERROR; - - $p_filename = $p_filedescr['filename']; + // ------ Look for file comment + if (isset($p_filedescr['comment'])) { + $p_header['comment_len'] = strlen($p_filedescr['comment']); + $p_header['comment'] = $p_filedescr['comment']; + } + else { + $p_header['comment_len'] = 0; + $p_header['comment'] = ''; + } + // ----- Look for pre-add callback + if (isset($p_options[PCLZIP_CB_PRE_ADD])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_header['status'] = "skipped"; + $v_result = 1; + } - if (($v_file = @fopen($p_filename, "rb")) == 0) { - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); - return PclZip::errorCode(); - } + // ----- Update the informations + // Only some fields can be modified + if ($p_header['stored_filename'] != $v_local_header['stored_filename']) { + $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']); + } + } - $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; - if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) { - fclose($v_file); - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); - return PclZip::errorCode(); - } + // ----- Look for empty stored filename + if ($p_header['stored_filename'] == "") { + $p_header['status'] = "filtered"; + } + + // ----- Check the path length + if (strlen($p_header['stored_filename']) > 0xFF) { + $p_header['status'] = 'filename_too_long'; + } - $v_size = filesize($p_filename); - while ($v_size != 0) { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($v_file, $v_read_size); - @gzputs($v_file_compressed, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + // ----- Look if no error, or file not skipped + if ($p_header['status'] == 'ok') { - @fclose($v_file); - @gzclose($v_file_compressed); + // ----- Look for a file + if ($p_filedescr['type'] == 'file') { + // ----- Look for using temporary file to zip + if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) + && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) + || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) { + $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options); + if ($v_result < PCLZIP_ERR_NO_ERROR) { + return $v_result; + } + } + + // ----- Use "in memory" zip algo + else { - if (filesize($v_gzip_temp_name) < 18) { - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes'); - return PclZip::errorCode(); - } + // ----- Open the source file + if (($v_file = @fopen($p_filename, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); + return PclZip::errorCode(); + } - if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) { - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); - return PclZip::errorCode(); - } + // ----- Read the file content + $v_content = @fread($v_file, $p_header['size']); - $v_binary_data = @fread($v_file_compressed, 10); - $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data); + // ----- Close the file + @fclose($v_file); - $v_data_header['os'] = bin2hex($v_data_header['os']); + // ----- Calculate the CRC + $p_header['crc'] = @crc32($v_content); + + // ----- Look for no compression + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { + // ----- Set header parameters + $p_header['compressed_size'] = $p_header['size']; + $p_header['compression'] = 0; + } + + // ----- Look for normal compression + else { + // ----- Compress the content + $v_content = @gzdeflate($v_content); - @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8); - $v_binary_data = @fread($v_file_compressed, 8); - $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data); + // ----- Set header parameters + $p_header['compressed_size'] = strlen($v_content); + $p_header['compression'] = 8; + } + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + @fclose($v_file); + return $v_result; + } - $p_header['compression'] = ord($v_data_header['cm']); - $p_header['crc'] = $v_data_footer['crc']; - $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18; + // ----- Write the compressed (or not) content + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); - @fclose($v_file_compressed); + } - if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { - return $v_result; - } + } - if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) - { - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); - return PclZip::errorCode(); - } + // ----- Look for a virtual file (a file from string) + else if ($p_filedescr['type'] == 'virtual_file') { + + $v_content = $p_filedescr['content']; - fseek($v_file_compressed, 10); - $v_size = $p_header['compressed_size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($v_file_compressed, $v_read_size); - @fwrite($this->zip_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + // ----- Calculate the CRC + $p_header['crc'] = @crc32($v_content); + + // ----- Look for no compression + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { + // ----- Set header parameters + $p_header['compressed_size'] = $p_header['size']; + $p_header['compression'] = 0; + } + + // ----- Look for normal compression + else { + // ----- Compress the content + $v_content = @gzdeflate($v_content); - @fclose($v_file_compressed); + // ----- Set header parameters + $p_header['compressed_size'] = strlen($v_content); + $p_header['compression'] = 8; + } + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + @fclose($v_file); + return $v_result; + } - @unlink($v_gzip_temp_name); - - return $v_result; -} + // ----- Write the compressed (or not) content + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); + } -function privCalculateStoredFilename(&$p_filedescr, &$p_options) -{ - $v_result=1; - - $p_filename = $p_filedescr['filename']; - if (isset($p_options[PCLZIP_OPT_ADD_PATH])) { - $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH]; - } - else { - $p_add_dir = ''; - } - if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) { - $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH]; - } - else { - $p_remove_dir = ''; - } - if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { - $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH]; - } - else { - $p_remove_all_dir = 0; - } + // ----- Look for a directory + else if ($p_filedescr['type'] == 'folder') { + // ----- Look for directory last '/' + if (@substr($p_header['stored_filename'], -1) != '/') { + $p_header['stored_filename'] .= '/'; + } - if (isset($p_filedescr['new_full_name'])) { - $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']); - } - - else { + // ----- Set the file properties + $p_header['size'] = 0; + //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked + $p_header['external'] = 0x00000010; // Value for a folder : to be checked - if (isset($p_filedescr['new_short_name'])) { - $v_path_info = pathinfo($p_filename); - $v_dir = ''; - if ($v_path_info['dirname'] != '') { - $v_dir = $v_path_info['dirname'].'/'; + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) + { + return $v_result; + } } - $v_stored_filename = $v_dir.$p_filedescr['new_short_name']; - } - else { - $v_stored_filename = $p_filename; } - if ($p_remove_all_dir) { - $v_stored_filename = basename($p_filename); - } - else if ($p_remove_dir != "") { - if (substr($p_remove_dir, -1) != '/') - $p_remove_dir .= "/"; + // ----- Look for post-add callback + if (isset($p_options[PCLZIP_CB_POST_ADD])) { - if ( (substr($p_filename, 0, 2) == "./") - || (substr($p_remove_dir, 0, 2) == "./")) { - - if ( (substr($p_filename, 0, 2) == "./") - && (substr($p_remove_dir, 0, 2) != "./")) { - $p_remove_dir = "./".$p_remove_dir; - } - if ( (substr($p_filename, 0, 2) != "./") - && (substr($p_remove_dir, 0, 2) == "./")) { - $p_remove_dir = substr($p_remove_dir, 2); - } - } + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_header, $v_local_header); - $v_compare = PclZipUtilPathInclusion($p_remove_dir, - $v_stored_filename); - if ($v_compare > 0) { - if ($v_compare == 2) { - $v_stored_filename = ""; - } - else { - $v_stored_filename = substr($v_stored_filename, - strlen($p_remove_dir)); - } + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header); + if ($v_result == 0) { + // ----- Ignored + $v_result = 1; } + + // ----- Update the informations + // Nothing can be modified } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFileUsingTempFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options) + { + $v_result=PCLZIP_ERR_NO_ERROR; - $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename); - - if ($p_add_dir != "") { - if (substr($p_add_dir, -1) == "/") - $v_stored_filename = $p_add_dir.$v_stored_filename; - else - $v_stored_filename = $p_add_dir."/".$v_stored_filename; + // ----- Working variable + $p_filename = $p_filedescr['filename']; + + + // ----- Open the source file + if (($v_file = @fopen($p_filename, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); + return PclZip::errorCode(); } - } - $v_stored_filename = PclZipUtilPathReduction($v_stored_filename); - $p_filedescr['stored_filename'] = $v_stored_filename; - - return $v_result; -} + // ----- Creates a compressed temporary file + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; + if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) { + fclose($v_file); + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); + return PclZip::errorCode(); + } -function privWriteFileHeader(&$p_header) -{ - $v_result=1; + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = filesize($p_filename); + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_file, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @gzputs($v_file_compressed, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } - $p_header['offset'] = ftell($this->zip_fd); + // ----- Close the file + @fclose($v_file); + @gzclose($v_file_compressed); - $v_date = getdate($p_header['mtime']); - $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; - $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + // ----- Check the minimum file size + if (filesize($v_gzip_temp_name) < 18) { + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes'); + return PclZip::errorCode(); + } - $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, - $p_header['version_extracted'], $p_header['flag'], - $p_header['compression'], $v_mtime, $v_mdate, - $p_header['crc'], $p_header['compressed_size'], - $p_header['size'], - strlen($p_header['stored_filename']), - $p_header['extra_len']); + // ----- Extract the compressed attributes + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); + } - fputs($this->zip_fd, $v_binary_data, 30); + // ----- Read the gzip file header + $v_binary_data = @fread($v_file_compressed, 10); + $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data); - if (strlen($p_header['stored_filename']) != 0) - { - fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); - } - if ($p_header['extra_len'] != 0) - { - fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); - } + // ----- Check some parameters + $v_data_header['os'] = bin2hex($v_data_header['os']); - return $v_result; -} + // ----- Read the gzip file footer + @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8); + $v_binary_data = @fread($v_file_compressed, 8); + $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data); -function privWriteCentralFileHeader(&$p_header) -{ - $v_result=1; + // ----- Set the attributes + $p_header['compression'] = ord($v_data_header['cm']); + //$p_header['mtime'] = $v_data_header['mtime']; + $p_header['crc'] = $v_data_footer['crc']; + $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18; + // ----- Close the file + @fclose($v_file_compressed); - $v_date = getdate($p_header['mtime']); - $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; - $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + return $v_result; + } + // ----- Add the compressed data + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) + { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); + } - $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, - $p_header['version'], $p_header['version_extracted'], - $p_header['flag'], $p_header['compression'], - $v_mtime, $v_mdate, $p_header['crc'], - $p_header['compressed_size'], $p_header['size'], - strlen($p_header['stored_filename']), - $p_header['extra_len'], $p_header['comment_len'], - $p_header['disk'], $p_header['internal'], - $p_header['external'], $p_header['offset']); + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + fseek($v_file_compressed, 10); + $v_size = $p_header['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_file_compressed, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } - fputs($this->zip_fd, $v_binary_data, 46); + // ----- Close the file + @fclose($v_file_compressed); - if (strlen($p_header['stored_filename']) != 0) - { - fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); - } - if ($p_header['extra_len'] != 0) - { - fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); + // ----- Unlink the temporary file + @unlink($v_gzip_temp_name); + + // ----- Return + return $v_result; } - if ($p_header['comment_len'] != 0) + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCalculateStoredFilename() + // Description : + // Based on file descriptor properties and global options, this method + // calculate the filename that will be stored in the archive. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privCalculateStoredFilename(&$p_filedescr, &$p_options) { - fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']); - } - - return $v_result; -} + $v_result=1; + + // ----- Working variables + $p_filename = $p_filedescr['filename']; + if (isset($p_options[PCLZIP_OPT_ADD_PATH])) { + $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH]; + } + else { + $p_add_dir = ''; + } + if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) { + $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH]; + } + else { + $p_remove_dir = ''; + } + if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + else { + $p_remove_all_dir = 0; + } -function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) -{ - $v_result=1; - $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, - $p_nb_entries, $p_size, - $p_offset, strlen($p_comment)); + // ----- Look for full name change + if (isset($p_filedescr['new_full_name'])) { + // ----- Remove drive letter if any + $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']); + } + + // ----- Look for path and/or short name change + else { - fputs($this->zip_fd, $v_binary_data, 22); + // ----- Look for short name change + // Its when we cahnge just the filename but not the path + if (isset($p_filedescr['new_short_name'])) { + $v_path_info = pathinfo($p_filename); + $v_dir = ''; + if ($v_path_info['dirname'] != '') { + $v_dir = $v_path_info['dirname'].'/'; + } + $v_stored_filename = $v_dir.$p_filedescr['new_short_name']; + } + else { + // ----- Calculate the stored filename + $v_stored_filename = $p_filename; + } - if (strlen($p_comment) != 0) - { - fputs($this->zip_fd, $p_comment, strlen($p_comment)); - } + // ----- Look for all path to remove + if ($p_remove_all_dir) { + $v_stored_filename = basename($p_filename); + } + // ----- Look for partial path remove + else if ($p_remove_dir != "") { + if (substr($p_remove_dir, -1) != '/') + $p_remove_dir .= "/"; - return $v_result; -} + if ( (substr($p_filename, 0, 2) == "./") + || (substr($p_remove_dir, 0, 2) == "./")) { + + if ( (substr($p_filename, 0, 2) == "./") + && (substr($p_remove_dir, 0, 2) != "./")) { + $p_remove_dir = "./".$p_remove_dir; + } + if ( (substr($p_filename, 0, 2) != "./") + && (substr($p_remove_dir, 0, 2) == "./")) { + $p_remove_dir = substr($p_remove_dir, 2); + } + } -function privList(&$p_list) -{ - $v_result=1; + $v_compare = PclZipUtilPathInclusion($p_remove_dir, + $v_stored_filename); + if ($v_compare > 0) { + if ($v_compare == 2) { + $v_stored_filename = ""; + } + else { + $v_stored_filename = substr($v_stored_filename, + strlen($p_remove_dir)); + } + } + } + + // ----- Remove drive letter if any + $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename); + + // ----- Look for path to add + if ($p_add_dir != "") { + if (substr($p_add_dir, -1) == "/") + $v_stored_filename = $p_add_dir.$v_stored_filename; + else + $v_stored_filename = $p_add_dir."/".$v_stored_filename; + } + } - $this->privDisableMagicQuotes(); + // ----- Filename (reduce the path of stored name) + $v_stored_filename = PclZipUtilPathReduction($v_stored_filename); + $p_filedescr['stored_filename'] = $v_stored_filename; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- - if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) + // -------------------------------------------------------------------------------- + // Function : privWriteFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteFileHeader(&$p_header) { - $this->privSwapBackMagicQuotes(); - - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); + $v_result=1; + + // ----- Store the offset position of the file + $p_header['offset'] = ftell($this->zip_fd); + + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + + // ----- Packed data + $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, + $p_header['version_extracted'], $p_header['flag'], + $p_header['compression'], $v_mtime, $v_mdate, + $p_header['crc'], $p_header['compressed_size'], + $p_header['size'], + strlen($p_header['stored_filename']), + $p_header['extra_len']); + + // ----- Write the first 148 bytes of the header in the archive + fputs($this->zip_fd, $v_binary_data, 30); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) + { + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) + { + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); + } - return PclZip::errorCode(); + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + // -------------------------------------------------------------------------------- + // Function : privWriteCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteCentralFileHeader(&$p_header) { - $this->privSwapBackMagicQuotes(); + $v_result=1; + + // TBC + //for(reset($p_header); $key = key($p_header); next($p_header)) { + //} + + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + + + // ----- Packed data + $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, + $p_header['version'], $p_header['version_extracted'], + $p_header['flag'], $p_header['compression'], + $v_mtime, $v_mdate, $p_header['crc'], + $p_header['compressed_size'], $p_header['size'], + strlen($p_header['stored_filename']), + $p_header['extra_len'], $p_header['comment_len'], + $p_header['disk'], $p_header['internal'], + $p_header['external'], $p_header['offset']); + + // ----- Write the 42 bytes of the header in the zip file + fputs($this->zip_fd, $v_binary_data, 46); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) + { + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) + { + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); + } + if ($p_header['comment_len'] != 0) + { + fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']); + } + + // ----- Return return $v_result; } + // -------------------------------------------------------------------------------- - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_central_dir['offset'])) + // -------------------------------------------------------------------------------- + // Function : privWriteCentralHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) { - $this->privSwapBackMagicQuotes(); + $v_result=1; - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + // ----- Packed data + $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, + $p_nb_entries, $p_size, + $p_offset, strlen($p_comment)); - return PclZip::errorCode(); - } + // ----- Write the 22 bytes of the header in the zip file + fputs($this->zip_fd, $v_binary_data, 22); - for ($i=0; $i<$v_central_dir['entries']; $i++) - { - if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) + // ----- Write the variable fields + if (strlen($p_comment) != 0) { - $this->privSwapBackMagicQuotes(); - return $v_result; + fputs($this->zip_fd, $p_comment, strlen($p_comment)); } - $v_header['index'] = $i; - $this->privConvertHeader2FileInfo($v_header, $p_list[$i]); - unset($v_header); + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - $this->privCloseFd(); - - $this->privSwapBackMagicQuotes(); + // -------------------------------------------------------------------------------- + // Function : privList() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privList(&$p_list) + { + $v_result=1; - return $v_result; -} + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); -function privConvertHeader2FileInfo($p_header, &$p_info) -{ - $v_result=1; + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) + { + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); - $v_temp_path = PclZipUtilPathReduction($p_header['filename']); - $p_info['filename'] = $v_temp_path; - $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']); - $p_info['stored_filename'] = $v_temp_path; - $p_info['size'] = $p_header['size']; - $p_info['compressed_size'] = $p_header['compressed_size']; - $p_info['mtime'] = $p_header['mtime']; - $p_info['comment'] = $p_header['comment']; - $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); - $p_info['index'] = $p_header['index']; - $p_info['status'] = $p_header['status']; - $p_info['crc'] = $p_header['crc']; + // ----- Return + return PclZip::errorCode(); + } - return $v_result; -} + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privSwapBackMagicQuotes(); + return $v_result; + } -function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) -{ - $v_result=1; + // ----- Go to beginning of Central Dir + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_central_dir['offset'])) + { + $this->privSwapBackMagicQuotes(); - $this->privDisableMagicQuotes(); + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - if ( ($p_path == "") - || ( (substr($p_path, 0, 1) != "/") - && (substr($p_path, 0, 3) != "../") - && (substr($p_path,1,2)!=":/"))) - $p_path = "./".$p_path; + // ----- Return + return PclZip::errorCode(); + } - if (($p_path != "./") && ($p_path != "/")) - { - while (substr($p_path, -1) == "/") + // ----- Read each entry + for ($i=0; $i<$v_central_dir['entries']; $i++) { - $p_path = substr($p_path, 0, strlen($p_path)-1); + // ----- Read the file header + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) + { + $this->privSwapBackMagicQuotes(); + return $v_result; + } + $v_header['index'] = $i; + + // ----- Get the only interesting attributes + $this->privConvertHeader2FileInfo($v_header, $p_list[$i]); + unset($v_header); } - } - if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) - { - $p_remove_path .= '/'; - } - $p_remove_path_size = strlen($p_remove_path); + // ----- Close the zip file + $this->privCloseFd(); - if (($v_result = $this->privOpenFd('rb')) != 1) - { + // ----- Magic quotes trick $this->privSwapBackMagicQuotes(); + + // ----- Return return $v_result; } - - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privConvertHeader2FileInfo() + // Description : + // This function takes the file informations from the central directory + // entries and extract the interesting parameters that will be given back. + // The resulting file infos are set in the array $p_info + // $p_info['filename'] : Filename with full path. Given by user (add), + // extracted in the filesystem (extract). + // $p_info['stored_filename'] : Stored filename in the archive. + // $p_info['size'] = Size of the file. + // $p_info['compressed_size'] = Compressed size of the file. + // $p_info['mtime'] = Last modification date of the file. + // $p_info['comment'] = Comment associated with the file. + // $p_info['folder'] = true/false : indicates if the entry is a folder or not. + // $p_info['status'] = status of the action on the file. + // $p_info['crc'] = CRC of the file content. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privConvertHeader2FileInfo($p_header, &$p_info) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - + $v_result=1; + + // ----- Get the interesting attributes + $v_temp_path = PclZipUtilPathReduction($p_header['filename']); + $p_info['filename'] = $v_temp_path; + $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']); + $p_info['stored_filename'] = $v_temp_path; + $p_info['size'] = $p_header['size']; + $p_info['compressed_size'] = $p_header['compressed_size']; + $p_info['mtime'] = $p_header['mtime']; + $p_info['comment'] = $p_header['comment']; + $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); + $p_info['index'] = $p_header['index']; + $p_info['status'] = $p_header['status']; + $p_info['crc'] = $p_header['crc']; + + // ----- Return return $v_result; } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractByRule() + // Description : + // Extract a file or directory depending of rules (by index, by name, ...) + // Parameters : + // $p_file_list : An array where will be placed the properties of each + // extracted file + // $p_path : Path to add while writing the extracted files + // $p_remove_path : Path to remove (from the file memorized path) while writing the + // extracted files. If the path does not match the file path, + // the file is extracted with its memorized path. + // $p_remove_path does not apply to 'list' mode. + // $p_path and $p_remove_path are commulative. + // Return Values : + // 1 on success,0 or less on error (see error code list) + // -------------------------------------------------------------------------------- + function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) + { + $v_result=1; - $v_pos_entry = $v_central_dir['offset']; + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); - $j_start = 0; - for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) - { + // ----- Check the path + if ( ($p_path == "") + || ( (substr($p_path, 0, 1) != "/") + && (substr($p_path, 0, 3) != "../") + && (substr($p_path,1,2)!=":/"))) + $p_path = "./".$p_path; - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_pos_entry)) + // ----- Reduce the path last (and duplicated) '/' + if (($p_path != "./") && ($p_path != "/")) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); + // ----- Look for the path end '/' + while (substr($p_path, -1) == "/") + { + $p_path = substr($p_path, 0, strlen($p_path)-1); + } + } - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + // ----- Look for path to remove format (should end by /) + if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) + { + $p_remove_path .= '/'; + } + $p_remove_path_size = strlen($p_remove_path); - return PclZip::errorCode(); + // ----- Open the zip file + if (($v_result = $this->privOpenFd('rb')) != 1) + { + $this->privSwapBackMagicQuotes(); + return $v_result; } - $v_header = array(); - if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { + // ----- Close the zip file $this->privCloseFd(); $this->privSwapBackMagicQuotes(); return $v_result; } - $v_header['index'] = $i; + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; - $v_pos_entry = ftell($this->zip_fd); + // ----- Read each entry + $j_start = 0; + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) + { - $v_extract = false; + // ----- Read next Central dir entry + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_pos_entry)) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); - if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) - && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - for ($j=0; ($jprivReadCentralFileHeader($v_header)) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); - if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) - && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { - $v_extract = true; - } - } - elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { - $v_extract = true; - } - } - } + return $v_result; + } - else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) - && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + // ----- Store the index + $v_header['index'] = $i; - if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { - $v_extract = true; - } - } + // ----- Store the file position + $v_pos_entry = ftell($this->zip_fd); - else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) - && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { - - for ($j=$j_start; ($j=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { - $v_extract = true; - } - if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { - $j_start = $j+1; - } + // ----- Look for extract by name rule + if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { - if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { - break; - } - } - } + // ----- Look if the filename is in the list + for ($j=0; ($j strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) + && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_extract = true; + } + } + // ----- Look for a filename + elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + $v_extract = true; + } + } + } - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + // ----- Look for extract by ereg rule + // ereg() is deprecated with PHP 5.3 + /* + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { - $this->privSwapBackMagicQuotes(); - - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, - "Filename '".$v_header['stored_filename']."' is " - ."compressed by an unsupported compression " - ."method (".$v_header['compression'].") "); + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } + */ - return PclZip::errorCode(); - } - } - - if (($v_extract) && (($v_header['flag'] & 1) == 1)) { - $v_header['status'] = 'unsupported_encryption'; + // ----- Look for extract by preg rule + else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } - $this->privSwapBackMagicQuotes(); + // ----- Look for extract by index rule + else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + + // ----- Look if the index is in the list + for ($j=$j_start; ($j=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + $v_extract = true; + } + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } + + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { + break; + } + } + } - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, - "Unsupported encryption for " - ." filename '".$v_header['stored_filename'] - ."'"); + // ----- Look for no rule, which means extract all the archive + else { + $v_extract = true; + } - return PclZip::errorCode(); - } - } + // ----- Check compression method + if ( ($v_extract) + && ( ($v_header['compression'] != 8) + && ($v_header['compression'] != 0))) { + $v_header['status'] = 'unsupported_compression'; - if (($v_extract) && ($v_header['status'] != 'ok')) { - $v_result = $this->privConvertHeader2FileInfo($v_header, - $p_file_list[$v_nb_extracted++]); - if ($v_result != 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result; - } + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - $v_extract = false; - } - - if ($v_extract) - { + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, + "Filename '".$v_header['stored_filename']."' is " + ."compressed by an unsupported compression " + ."method (".$v_header['compression'].") "); - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_header['offset'])) - { - $this->privCloseFd(); + return PclZip::errorCode(); + } + } + + // ----- Check encrypted files + if (($v_extract) && (($v_header['flag'] & 1) == 1)) { + $v_header['status'] = 'unsupported_encryption'; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - $this->privSwapBackMagicQuotes(); + $this->privSwapBackMagicQuotes(); - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, + "Unsupported encryption for " + ." filename '".$v_header['stored_filename'] + ."'"); - return PclZip::errorCode(); - } + return PclZip::errorCode(); + } + } - if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) { + // ----- Look for real extraction + if (($v_extract) && ($v_header['status'] != 'ok')) { + $v_result = $this->privConvertHeader2FileInfo($v_header, + $p_file_list[$v_nb_extracted++]); + if ($v_result != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } - $v_result1 = $this->privExtractFileAsString($v_header, $v_string); - if ($v_result1 < 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result1; - } + $v_extract = false; + } + + // ----- Look for real extraction + if ($v_extract) + { - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) + // ----- Go to the file position + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_header['offset'])) { + // ----- Close the zip file $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); - return $v_result; + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); } - $p_file_list[$v_nb_extracted]['content'] = $v_string; + // ----- Look for extraction as string + if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) { - $v_nb_extracted++; - - if ($v_result1 == 2) { - break; - } - } - elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) - && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { - $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); - if ($v_result1 < 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result1; - } + $v_string = ''; + + // ----- Extracting the file + $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Set the file content + $p_file_list[$v_nb_extracted]['content'] = $v_string; - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result; + // ----- Next extracted file + $v_nb_extracted++; + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } } + // ----- Look for extraction in standard output + elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) + && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { + // ----- Extracting the file in standard output + $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } - if ($v_result1 == 2) { - break; - } - } - else { - $v_result1 = $this->privExtractFile($v_header, - $p_path, $p_remove_path, - $p_remove_all_path, - $p_options); - if ($v_result1 < 1) { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - return $v_result1; + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } } + // ----- Look for normal extraction + else { + // ----- Extracting the file + $v_result1 = $this->privExtractFile($v_header, + $p_path, $p_remove_path, + $p_remove_all_path, + $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) - { - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); - return $v_result; - } + return $v_result; + } - if ($v_result1 == 2) { - break; + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } } } } - } - $this->privCloseFd(); - $this->privSwapBackMagicQuotes(); - - return $v_result; -} - -function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) -{ - $v_result=1; + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); - if (($v_result = $this->privReadFileHeader($v_header)) != 1) - { + // ----- Return return $v_result; } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFile() + // Description : + // Parameters : + // Return Values : + // + // 1 : ... ? + // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback + // -------------------------------------------------------------------------------- + function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) + { + $v_result=1; + // ----- Read the file header + if (($v_result = $this->privReadFileHeader($v_header)) != 1) + { + // ----- Return + return $v_result; + } - if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { - } - - if ($p_remove_all_path == true) { - if (($p_entry['external']&0x00000010)==0x00000010) { - - $p_entry['status'] = "filtered"; - return $v_result; - } + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } - $p_entry['filename'] = basename($p_entry['filename']); - } + // ----- Look for all path to remove + if ($p_remove_all_path == true) { + // ----- Look for folder entry that not need to be extracted + if (($p_entry['external']&0x00000010)==0x00000010) { - else if ($p_remove_path != "") - { - if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) - { + $p_entry['status'] = "filtered"; - $p_entry['status'] = "filtered"; + return $v_result; + } - return $v_result; + // ----- Get the basename of the path + $p_entry['filename'] = basename($p_entry['filename']); } - $p_remove_path_size = strlen($p_remove_path); - if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) + // ----- Look for path to remove + else if ($p_remove_path != "") { + if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) + { - $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); + // ----- Change the file status + $p_entry['status'] = "filtered"; - } - } + // ----- Return + return $v_result; + } - if ($p_path != '') { - $p_entry['filename'] = $p_path."/".$p_entry['filename']; - } - - if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { - $v_inclusion - = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], - $p_entry['filename']); - if ($v_inclusion == 0) { + $p_remove_path_size = strlen($p_remove_path); + if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) + { - PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, - "Filename '".$p_entry['filename']."' is " - ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); + // ----- Remove the path + $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); - return PclZip::errorCode(); + } } - } - - if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - - eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); - if ($v_result == 0) { - $p_entry['status'] = "skipped"; - $v_result = 1; + // ----- Add the path + if ($p_path != '') { + $p_entry['filename'] = $p_path."/".$p_entry['filename']; } - if ($v_result == 2) { - $p_entry['status'] = "aborted"; - $v_result = PCLZIP_ERR_USER_ABORTED; + // ----- Check a base_dir_restriction + if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { + $v_inclusion + = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], + $p_entry['filename']); + if ($v_inclusion == 0) { + + PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, + "Filename '".$p_entry['filename']."' is " + ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); + + return PclZip::errorCode(); + } } - $p_entry['filename'] = $v_local_header['filename']; - } + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } - if ($p_entry['status'] == 'ok') { - if (file_exists($p_entry['filename'])) - { + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { - if (is_dir($p_entry['filename'])) + // ----- Look for specific actions while the file exist + if (file_exists($p_entry['filename'])) { - $p_entry['status'] = "already_a_directory"; - - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + // ----- Look if file is a directory + if (is_dir($p_entry['filename'])) + { + + // ----- Change the file status + $p_entry['status'] = "already_a_directory"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, - "Filename '".$p_entry['filename']."' is " - ."already used by an existing directory"); + PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, + "Filename '".$p_entry['filename']."' is " + ."already used by an existing directory"); - return PclZip::errorCode(); + return PclZip::errorCode(); + } } - } - else if (!is_writeable($p_entry['filename'])) - { + // ----- Look if file is write protected + else if (!is_writeable($p_entry['filename'])) + { - $p_entry['status'] = "write_protected"; + // ----- Change the file status + $p_entry['status'] = "write_protected"; - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, - "Filename '".$p_entry['filename']."' exists " - ."and is write protected"); + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, + "Filename '".$p_entry['filename']."' exists " + ."and is write protected"); - return PclZip::errorCode(); + return PclZip::errorCode(); + } } - } - else if (filemtime($p_entry['filename']) > $p_entry['mtime']) - { - if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) - && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) { + // ----- Look if the extracted file is older + else if (filemtime($p_entry['filename']) > $p_entry['mtime']) + { + // ----- Change the file status + if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) + && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) { + } + else { + $p_entry['status'] = "newer_exist"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, + "Newer version of '".$p_entry['filename']."' exists " + ."and option PCLZIP_OPT_REPLACE_NEWER is not selected"); + + return PclZip::errorCode(); + } + } } else { - $p_entry['status'] = "newer_exist"; - - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { - - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, - "Newer version of '".$p_entry['filename']."' exists " - ."and option PCLZIP_OPT_REPLACE_NEWER is not selected"); - - return PclZip::errorCode(); - } } } - else { - } - } - - else { - if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) - $v_dir_to_check = $p_entry['filename']; - else if (!strstr($p_entry['filename'], "/")) - $v_dir_to_check = ""; - else - $v_dir_to_check = dirname($p_entry['filename']); - - if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { - $p_entry['status'] = "path_creation_fail"; + // ----- Check the directory availability and create it if necessary + else { + if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) + $v_dir_to_check = $p_entry['filename']; + else if (!strstr($p_entry['filename'], "/")) + $v_dir_to_check = ""; + else + $v_dir_to_check = dirname($p_entry['filename']); - $v_result = 1; + if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { + + // ----- Change the file status + $p_entry['status'] = "path_creation_fail"; + + // ----- Return + //return $v_result; + $v_result = 1; + } } } - } - - if ($p_entry['status'] == 'ok') { - - if (!(($p_entry['external']&0x00000010)==0x00000010)) - { - if ($p_entry['compression'] == 0) { - if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) - { + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { - $p_entry['status'] = "write_error"; + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) + { + // ----- Look for not compressed file + if ($p_entry['compression'] == 0) { - return $v_result; - } + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) + { + // ----- Change the file status + $p_entry['status'] = "write_error"; - $v_size = $p_entry['compressed_size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($this->zip_fd, $v_read_size); - /* Try to speed up the code - $v_binary_data = pack('a'.$v_read_size, $v_buffer); - @fwrite($v_dest_file, $v_binary_data, $v_read_size); - */ - @fwrite($v_dest_file, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + // ----- Return + return $v_result; + } - fclose($v_dest_file); - touch($p_entry['filename'], $p_entry['mtime']); - + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + /* Try to speed up the code + $v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_binary_data, $v_read_size); + */ + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } - } - else { - if (($p_entry['flag'] & 1) == 1) { - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.'); - return PclZip::errorCode(); - } + // ----- Closing the destination file + fclose($v_dest_file); + // ----- Change the file mtime + touch($p_entry['filename'], $p_entry['mtime']); + - if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) - && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) - || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) - && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) { - $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options); - if ($v_result < PCLZIP_ERR_NO_ERROR) { - return $v_result; - } } - else { + // ----- TBC + // Need to be finished + if (($p_entry['flag'] & 1) == 1) { + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.'); + return PclZip::errorCode(); + } - - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); - - $v_file_content = @gzinflate($v_buffer); - unset($v_buffer); - if ($v_file_content === FALSE) { - $p_entry['status'] = "error"; - - return $v_result; + // ----- Look for using temporary file to unzip + if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) + && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) + || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) { + $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options); + if ($v_result < PCLZIP_ERR_NO_ERROR) { + return $v_result; + } } - if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { - - $p_entry['status'] = "write_error"; + // ----- Look for extract in memory + else { - return $v_result; + + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = @gzinflate($v_buffer); + unset($v_buffer); + if ($v_file_content === FALSE) { + + // ----- Change the file status + // TBC + $p_entry['status'] = "error"; + + return $v_result; + } + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + + // ----- Change the file status + $p_entry['status'] = "write_error"; + + return $v_result; + } + + // ----- Write the uncompressed data + @fwrite($v_dest_file, $v_file_content, $p_entry['size']); + unset($v_file_content); + + // ----- Closing the destination file + @fclose($v_dest_file); + } - @fwrite($v_dest_file, $v_file_content, $p_entry['size']); - unset($v_file_content); - - @fclose($v_dest_file); - + // ----- Change the file mtime + @touch($p_entry['filename'], $p_entry['mtime']); } - @touch($p_entry['filename'], $p_entry['mtime']); - } + // ----- Look for chmod option + if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { - if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { + // ----- Change the mode of the file + @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]); + } - @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]); } - } - } - -if ($p_entry['status'] == "aborted") { - $p_entry['status'] = "skipped"; -} - - elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { - - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - - eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); - if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } + + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } } - } - return $v_result; -} - -function privExtractFileUsingTempFile(&$p_entry, &$p_options) -{ - $v_result=1; - - $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; - if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) { - fclose($v_file); - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); - return PclZip::errorCode(); + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - - $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3)); - @fwrite($v_dest_file, $v_binary_data, 10); - - $v_size = $p_entry['compressed_size']; - while ($v_size != 0) + // -------------------------------------------------------------------------------- + // Function : privExtractFileUsingTempFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileUsingTempFile(&$p_entry, &$p_options) { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($this->zip_fd, $v_read_size); - @fwrite($v_dest_file, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + $v_result=1; + + // ----- Creates a temporary file + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; + if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) { + fclose($v_file); + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); + return PclZip::errorCode(); + } - $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']); - @fwrite($v_dest_file, $v_binary_data, 8); - @fclose($v_dest_file); + // ----- Write gz file format header + $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3)); + @fwrite($v_dest_file, $v_binary_data, 10); - if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { - $p_entry['status'] = "write_error"; - return $v_result; - } + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Write gz file format footer + $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']); + @fwrite($v_dest_file, $v_binary_data, 8); - if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) { + // ----- Close the temporary file @fclose($v_dest_file); - $p_entry['status'] = "read_error"; - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); - return PclZip::errorCode(); - } + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + $p_entry['status'] = "write_error"; + return $v_result; + } - $v_size = $p_entry['size']; - while ($v_size != 0) { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @gzread($v_src_file, $v_read_size); - @fwrite($v_dest_file, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } - @fclose($v_dest_file); - @gzclose($v_src_file); + // ----- Open the temporary gz file + if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) { + @fclose($v_dest_file); + $p_entry['status'] = "read_error"; + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); + } - @unlink($v_gzip_temp_name); - - return $v_result; -} -function privExtractFileInOutput(&$p_entry, &$p_options) -{ - $v_result=1; + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['size']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($v_src_file, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + @fclose($v_dest_file); + @gzclose($v_src_file); - if (($v_result = $this->privReadFileHeader($v_header)) != 1) { + // ----- Delete the temporary file + @unlink($v_gzip_temp_name); + + // ----- Return return $v_result; } + // -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- + // Function : privExtractFileInOutput() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileInOutput(&$p_entry, &$p_options) + { + $v_result=1; - if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { - } - - if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + // ----- Read the file header + if (($v_result = $this->privReadFileHeader($v_header)) != 1) { + return $v_result; + } - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); - if ($v_result == 0) { - $p_entry['status'] = "skipped"; - $v_result = 1; + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC } - if ($v_result == 2) { - $p_entry['status'] = "aborted"; - $v_result = PCLZIP_ERR_USER_ABORTED; - } + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } - $p_entry['filename'] = $v_local_header['filename']; - } + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } - if ($p_entry['status'] == 'ok') { + // ----- Trace - if (!(($p_entry['external']&0x00000010)==0x00000010)) { - if ($p_entry['compressed_size'] == $p_entry['size']) { + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) { + // ----- Look for not compressed file + if ($p_entry['compressed_size'] == $p_entry['size']) { - echo $v_buffer; - unset($v_buffer); - } - else { + // ----- Read the file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); - - $v_file_content = gzinflate($v_buffer); - unset($v_buffer); + // ----- Send the file to the output + echo $v_buffer; + unset($v_buffer); + } + else { + + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = gzinflate($v_buffer); + unset($v_buffer); - echo $v_file_content; - unset($v_file_content); + // ----- Send the file to the output + echo $v_file_content; + unset($v_file_content); + } } } - } -if ($p_entry['status'] == "aborted") { - $p_entry['status'] = "skipped"; -} + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } - elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { - $v_local_header = array(); - $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); - if ($v_result == 2) { - $v_result = PCLZIP_ERR_USER_ABORTED; + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } } + + return $v_result; } + // -------------------------------------------------------------------------------- - return $v_result; -} + // -------------------------------------------------------------------------------- + // Function : privExtractFileAsString() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) + { + $v_result=1; -function privExtractFileAsString(&$p_entry, &$p_string) -{ - $v_result=1; + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->privReadFileHeader($v_header)) != 1) + { + // ----- Return + return $v_result; + } - $v_header = array(); - if (($v_result = $this->privReadFileHeader($v_header)) != 1) - { - return $v_result; - } + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } - if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { - } + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } - if (!(($p_entry['external']&0x00000010)==0x00000010)) - { - if ($p_entry['compression'] == 0) { + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { - $p_string = @fread($this->zip_fd, $p_entry['compressed_size']); + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) { + // ----- Look for not compressed file + // if ($p_entry['compressed_size'] == $p_entry['size']) + if ($p_entry['compression'] == 0) { + + // ----- Reading the file + $p_string = @fread($this->zip_fd, $p_entry['compressed_size']); + } + else { + + // ----- Reading the file + $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + if (($p_string = @gzinflate($v_data)) === FALSE) { + // TBC + } + } + + // ----- Trace + } + else { + // TBC : error : can not extract a folder in a string + } + } - else { - $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } + + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); - if (($p_string = @gzinflate($v_data)) === FALSE) { + // ----- Swap the content to header + $v_local_header['content'] = $p_string; + $p_string = ''; + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + + // ----- Swap back the content to header + $p_string = $v_local_header['content']; + unset($v_local_header['content']); + + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; } } + // ----- Return + return $v_result; } - else { - } - - return $v_result; -} - -function privReadFileHeader(&$p_header) -{ - $v_result=1; - - $v_binary_data = @fread($this->zip_fd, 4); - $v_data = unpack('Vid', $v_binary_data); + // -------------------------------------------------------------------------------- - if ($v_data['id'] != 0x04034b50) + // -------------------------------------------------------------------------------- + // Function : privReadFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadFileHeader(&$p_header) { + $v_result=1; - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); - return PclZip::errorCode(); - } + // ----- Check signature + if ($v_data['id'] != 0x04034b50) + { - $v_binary_data = fread($this->zip_fd, 26); + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); - if (strlen($v_binary_data) != 26) - { - $p_header['filename'] = ""; - $p_header['status'] = "invalid_header"; + // ----- Return + return PclZip::errorCode(); + } - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->zip_fd, 26); - return PclZip::errorCode(); - } + // ----- Look for invalid block size + if (strlen($v_binary_data) != 26) + { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; - $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); - $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']); + // ----- Return + return PclZip::errorCode(); + } - if ($v_data['extra_len'] != 0) { - $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']); - } - else { - $p_header['extra'] = ''; - } + // ----- Extract the values + $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); - $p_header['version_extracted'] = $v_data['version']; - $p_header['compression'] = $v_data['compression']; - $p_header['size'] = $v_data['size']; - $p_header['compressed_size'] = $v_data['compressed_size']; - $p_header['crc'] = $v_data['crc']; - $p_header['flag'] = $v_data['flag']; - $p_header['filename_len'] = $v_data['filename_len']; - - $p_header['mdate'] = $v_data['mdate']; - $p_header['mtime'] = $v_data['mtime']; - if ($p_header['mdate'] && $p_header['mtime']) - { - $v_hour = ($p_header['mtime'] & 0xF800) >> 11; - $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; - $v_seconde = ($p_header['mtime'] & 0x001F)*2; + // ----- Get filename + $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']); - $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; - $v_month = ($p_header['mdate'] & 0x01E0) >> 5; - $v_day = $p_header['mdate'] & 0x001F; + // ----- Get extra_fields + if ($v_data['extra_len'] != 0) { + $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']); + } + else { + $p_header['extra'] = ''; + } - $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + // ----- Extract properties + $p_header['version_extracted'] = $v_data['version']; + $p_header['compression'] = $v_data['compression']; + $p_header['size'] = $v_data['size']; + $p_header['compressed_size'] = $v_data['compressed_size']; + $p_header['crc'] = $v_data['crc']; + $p_header['flag'] = $v_data['flag']; + $p_header['filename_len'] = $v_data['filename_len']; + + // ----- Recuperate date in UNIX format + $p_header['mdate'] = $v_data['mdate']; + $p_header['mtime'] = $v_data['mtime']; + if ($p_header['mdate'] && $p_header['mtime']) + { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; - } - else - { - $p_header['mtime'] = time(); - } + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + // ----- Get UNIX date format + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); - $p_header['stored_filename'] = $p_header['filename']; + } + else + { + $p_header['mtime'] = time(); + } - $p_header['status'] = "ok"; + // TBC + //for(reset($v_data); $key = key($v_data); next($v_data)) { + //} - return $v_result; -} + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; -function privReadCentralFileHeader(&$p_header) -{ - $v_result=1; + // ----- Set the status field + $p_header['status'] = "ok"; - $v_binary_data = @fread($this->zip_fd, 4); - $v_data = unpack('Vid', $v_binary_data); + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- - if ($v_data['id'] != 0x02014b50) + // -------------------------------------------------------------------------------- + // Function : privReadCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadCentralFileHeader(&$p_header) { + $v_result=1; - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); - return PclZip::errorCode(); - } + // ----- Check signature + if ($v_data['id'] != 0x02014b50) + { - $v_binary_data = fread($this->zip_fd, 42); + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); - if (strlen($v_binary_data) != 42) - { - $p_header['filename'] = ""; - $p_header['status'] = "invalid_header"; + // ----- Return + return PclZip::errorCode(); + } - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->zip_fd, 42); - return PclZip::errorCode(); - } + // ----- Look for invalid block size + if (strlen($v_binary_data) != 42) + { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; - $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); + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); - if ($p_header['filename_len'] != 0) - $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']); - else - $p_header['filename'] = ''; + // ----- Return + return PclZip::errorCode(); + } - if ($p_header['extra_len'] != 0) - $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']); - else - $p_header['extra'] = ''; + // ----- Extract the values + $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); - if ($p_header['comment_len'] != 0) - $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']); - else - $p_header['comment'] = ''; + // ----- Get filename + if ($p_header['filename_len'] != 0) + $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']); + else + $p_header['filename'] = ''; + // ----- Get extra + if ($p_header['extra_len'] != 0) + $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']); + else + $p_header['extra'] = ''; - if (1) - { - $v_hour = ($p_header['mtime'] & 0xF800) >> 11; - $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; - $v_seconde = ($p_header['mtime'] & 0x001F)*2; + // ----- Get comment + if ($p_header['comment_len'] != 0) + $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']); + else + $p_header['comment'] = ''; - $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; - $v_month = ($p_header['mdate'] & 0x01E0) >> 5; - $v_day = $p_header['mdate'] & 0x001F; + // ----- Extract properties - $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + // ----- Recuperate date in UNIX format + //if ($p_header['mdate'] && $p_header['mtime']) + // TBC : bug : this was ignoring time with 0/0/0 + if (1) + { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; - } - else - { - $p_header['mtime'] = time(); - } + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; - $p_header['stored_filename'] = $p_header['filename']; + // ----- Get UNIX date format + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); - $p_header['status'] = 'ok'; + } + else + { + $p_header['mtime'] = time(); + } - if (substr($p_header['filename'], -1) == '/') { - $p_header['external'] = 0x00000010; - } + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; + // ----- Set default status to ok + $p_header['status'] = 'ok'; - return $v_result; -} + // ----- Look if it is a directory + if (substr($p_header['filename'], -1) == '/') { + //$p_header['external'] = 0x41FF0010; + $p_header['external'] = 0x00000010; + } -function privCheckFileHeaders(&$p_local_header, &$p_central_header) -{ - $v_result=1; - if ($p_local_header['filename'] != $p_central_header['filename']) { - } - if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { - } - if ($p_local_header['flag'] != $p_central_header['flag']) { - } - if ($p_local_header['compression'] != $p_central_header['compression']) { - } - if ($p_local_header['mtime'] != $p_central_header['mtime']) { - } - if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { + // ----- Return + return $v_result; } - - if (($p_local_header['flag'] & 8) == 8) { - $p_local_header['size'] = $p_central_header['size']; - $p_local_header['compressed_size'] = $p_central_header['compressed_size']; - $p_local_header['crc'] = $p_central_header['crc']; + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCheckFileHeaders() + // Description : + // Parameters : + // Return Values : + // 1 on success, + // 0 on error; + // -------------------------------------------------------------------------------- + function privCheckFileHeaders(&$p_local_header, &$p_central_header) + { + $v_result=1; + + // ----- Check the static values + // TBC + if ($p_local_header['filename'] != $p_central_header['filename']) { + } + if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { + } + if ($p_local_header['flag'] != $p_central_header['flag']) { + } + if ($p_local_header['compression'] != $p_central_header['compression']) { + } + if ($p_local_header['mtime'] != $p_central_header['mtime']) { + } + if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { + } + + // ----- Look for flag bit 3 + if (($p_local_header['flag'] & 8) == 8) { + $p_local_header['size'] = $p_central_header['size']; + $p_local_header['compressed_size'] = $p_central_header['compressed_size']; + $p_local_header['crc'] = $p_central_header['crc']; + } + + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - return $v_result; -} - -function privReadEndCentralDir(&$p_central_dir) -{ - $v_result=1; - - $v_size = filesize($this->zipname); - @fseek($this->zip_fd, $v_size); - if (@ftell($this->zip_fd) != $v_size) + // -------------------------------------------------------------------------------- + // Function : privReadEndCentralDir() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadEndCentralDir(&$p_central_dir) { - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\''); + $v_result=1; - return PclZip::errorCode(); - } - - $v_found = 0; - if ($v_size > 26) { - @fseek($this->zip_fd, $v_size-22); - if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22)) + // ----- Go to the end of the zip file + $v_size = filesize($this->zipname); + @fseek($this->zip_fd, $v_size); + if (@ftell($this->zip_fd) != $v_size) { - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\''); + // ----- Return return PclZip::errorCode(); } - $v_binary_data = @fread($this->zip_fd, 4); - $v_data = @unpack('Vid', $v_binary_data); + // ----- First try : look if this is an archive with no commentaries (most of the time) + // in this case the end of central dir is at 22 bytes of the file end + $v_found = 0; + if ($v_size > 26) { + @fseek($this->zip_fd, $v_size-22); + if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); - if ($v_data['id'] == 0x06054b50) { - $v_found = 1; - } + // ----- Return + return PclZip::errorCode(); + } - $v_pos = ftell($this->zip_fd); - } + // ----- Read for bytes + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = @unpack('Vid', $v_binary_data); - if (!$v_found) { - if ($v_maximum_size > $v_size) - $v_maximum_size = $v_size; - @fseek($this->zip_fd, $v_size-$v_maximum_size); - if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size)) - { - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); + // ----- Check signature + if ($v_data['id'] == 0x06054b50) { + $v_found = 1; + } - return PclZip::errorCode(); + $v_pos = ftell($this->zip_fd); } - $v_pos = ftell($this->zip_fd); - $v_bytes = 0x00000000; - while ($v_pos < $v_size) - { - $v_byte = @fread($this->zip_fd, 1); - - $v_bytes = ($v_bytes << 8) | Ord($v_byte); - - if ($v_bytes == 0x504b0506) + // ----- Go back to the maximum possible size of the Central Dir End Record + if (!$v_found) { + $v_maximum_size = 65557; // 0xFFFF + 22; + if ($v_maximum_size > $v_size) + $v_maximum_size = $v_size; + @fseek($this->zip_fd, $v_size-$v_maximum_size); + if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size)) { - $v_pos++; - break; + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); + + // ----- Return + return PclZip::errorCode(); } - $v_pos++; - } + // ----- Read byte per byte in order to find the signature + $v_pos = ftell($this->zip_fd); + $v_bytes = 0x00000000; + while ($v_pos < $v_size) + { + // ----- Read a byte + $v_byte = @fread($this->zip_fd, 1); - if ($v_pos == $v_size) - { + // ----- Add the byte + //$v_bytes = ($v_bytes << 8) | Ord($v_byte); + // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number + // Otherwise on systems where we have 64bit integers the check below for the magic number will fail. + $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature"); + // ----- Compare the bytes + if ($v_bytes == 0x504b0506) + { + $v_pos++; + break; + } - return PclZip::errorCode(); - } - } + $v_pos++; + } - $v_binary_data = fread($this->zip_fd, 18); + // ----- Look if not found end of central dir + if ($v_pos == $v_size) + { - if (strlen($v_binary_data) != 18) - { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature"); - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); + // ----- Return + return PclZip::errorCode(); + } + } - return PclZip::errorCode(); - } + // ----- Read the first 18 bytes of the header + $v_binary_data = fread($this->zip_fd, 18); - $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); + // ----- Look for invalid block size + if (strlen($v_binary_data) != 18) + { - if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); - if (0) { - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, - 'The central dir is not at the end of the archive.' - .' Some trailing bytes exists after the archive.'); + // ----- Return + return PclZip::errorCode(); + } - return PclZip::errorCode(); - } - } + // ----- Extract the values + $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); - if ($v_data['comment_size'] != 0) { - $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']); - } - else - $p_central_dir['comment'] = ''; + // ----- Check the global size + if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { - $p_central_dir['entries'] = $v_data['entries']; - $p_central_dir['disk_entries'] = $v_data['disk_entries']; - $p_central_dir['offset'] = $v_data['offset']; - $p_central_dir['size'] = $v_data['size']; - $p_central_dir['disk'] = $v_data['disk']; - $p_central_dir['disk_start'] = $v_data['disk_start']; + // ----- Removed in release 2.2 see readme file + // The check of the file size is a little too strict. + // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. + // While decrypted, zip has training 0 bytes + if (0) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, + 'The central dir is not at the end of the archive.' + .' Some trailing bytes exists after the archive.'); + // ----- Return + return PclZip::errorCode(); + } + } - return $v_result; -} + // ----- Get comment + if ($v_data['comment_size'] != 0) { + $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']); + } + else + $p_central_dir['comment'] = ''; -function privDeleteByRule(&$p_result_list, &$p_options) -{ - $v_result=1; - $v_list_detail = array(); + $p_central_dir['entries'] = $v_data['entries']; + $p_central_dir['disk_entries'] = $v_data['disk_entries']; + $p_central_dir['offset'] = $v_data['offset']; + $p_central_dir['size'] = $v_data['size']; + $p_central_dir['disk'] = $v_data['disk']; + $p_central_dir['disk_start'] = $v_data['disk_start']; - if (($v_result=$this->privOpenFd('rb')) != 1) - { - return $v_result; - } + // TBC + //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) { + //} - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - $this->privCloseFd(); + // ----- Return return $v_result; } + // -------------------------------------------------------------------------------- - @rewind($this->zip_fd); - - $v_pos_entry = $v_central_dir['offset']; - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_pos_entry)) + // -------------------------------------------------------------------------------- + // Function : privDeleteByRule() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDeleteByRule(&$p_result_list, &$p_options) { - $this->privCloseFd(); + $v_result=1; + $v_list_detail = array(); - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - - return PclZip::errorCode(); - } - - $v_header_list = array(); - $j_start = 0; - for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) - { + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Return + return $v_result; + } - $v_header_list[$v_nb_extracted] = array(); - if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { $this->privCloseFd(); - return $v_result; } + // ----- Go to beginning of File + @rewind($this->zip_fd); - $v_header_list[$v_nb_extracted]['index'] = $i; - - $v_found = false; + // ----- Scan all the files + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_pos_entry)) + { + // ----- Close the zip file + $this->privCloseFd(); - if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) - && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - for ($j=0; ($j strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) - && (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])) { - $v_found = true; - } - elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */ - && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) { - $v_found = true; - } - } - elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { - $v_found = true; - } - } - } + // ----- Read the file header + $v_header_list[$v_nb_extracted] = array(); + if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); - else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) - && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + return $v_result; + } - if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { - $v_found = true; - } - } - else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) - && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + // ----- Store the index + $v_header_list[$v_nb_extracted]['index'] = $i; + + // ----- Look for the specific extract rules + $v_found = false; + + // ----- Look for extract by name rule + if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + + // ----- Look if the filename is in the list + for ($j=0; ($j strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) + && (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])) { + $v_found = true; + } + elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */ + && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_found = true; + } + } + // ----- Look for a filename + elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + $v_found = true; + } + } + } - for ($j=$j_start; ($j=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { - $v_found = true; - } - if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { - $j_start = $j+1; - } + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } + */ - if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { - break; - } - } - } - else { - $v_found = true; - } + // ----- Look for extract by preg rule + else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { - if ($v_found) - { - unset($v_header_list[$v_nb_extracted]); - } - else - { - $v_nb_extracted++; - } - } + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } - if ($v_nb_extracted > 0) { + // ----- Look for extract by index rule + else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { - $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + // ----- Look if the index is in the list + for ($j=$j_start; ($j=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + $v_found = true; + } + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } - if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) { - $this->privCloseFd(); + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { + break; + } + } + } + else { + $v_found = true; + } - return $v_result; + // ----- Look for deletion + if ($v_found) + { + unset($v_header_list[$v_nb_extracted]); + } + else + { + $v_nb_extracted++; } + } - for ($i=0; $i 0) { - @rewind($this->zip_fd); - if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) { - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + // ----- Creates a temporary zip archive + $v_temp_zip = new PclZip($v_zip_temp_name); - return PclZip::errorCode(); - } + // ----- Open the temporary zip file in write mode + if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) { + $this->privCloseFd(); - $v_local_header = array(); - if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) { - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); + // ----- Return + return $v_result; + } - return $v_result; - } - - if ($this->privCheckFileHeaders($v_local_header, - $v_header_list[$i]) != 1) { - } - unset($v_local_header); + // ----- Look which file need to be kept + for ($i=0; $iprivWriteFileHeader($v_header_list[$i])) != 1) { - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); + // ----- Calculate the position of the header + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); - return $v_result; - } + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); - if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) { - $this->privCloseFd(); - $v_temp_zip->privCloseFd(); - @unlink($v_zip_temp_name); + // ----- Return + return PclZip::errorCode(); + } - return $v_result; - } - } + // ----- Read the file header + $v_local_header = array(); + if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); - $v_offset = @ftell($v_temp_zip->zip_fd); + // ----- Return + return $v_result; + } + + // ----- Check that local file header is same as central file header + if ($this->privCheckFileHeaders($v_local_header, + $v_header_list[$i]) != 1) { + // TBC + } + unset($v_local_header); - for ($i=0; $iprivWriteCentralFileHeader($v_header_list[$i])) != 1) { - $v_temp_zip->privCloseFd(); - $this->privCloseFd(); - @unlink($v_zip_temp_name); + // ----- Write the file header + if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); - return $v_result; - } + // ----- Return + return $v_result; + } - $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); - } + // ----- Read/write the data block + if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + // ----- Return + return $v_result; + } + } - $v_comment = ''; - if (isset($p_options[PCLZIP_OPT_COMMENT])) { - $v_comment = $p_options[PCLZIP_OPT_COMMENT]; - } + // ----- Store the offset of the central dir + $v_offset = @ftell($v_temp_zip->zip_fd); - $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset; + // ----- Re-Create the Central Dir files header + for ($i=0; $iprivWriteCentralFileHeader($v_header_list[$i])) != 1) { + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); - if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) { - unset($v_header_list); - $v_temp_zip->privCloseFd(); - $this->privCloseFd(); - @unlink($v_zip_temp_name); + // ----- Return + return $v_result; + } - return $v_result; - } + // ----- Transform the header to a 'usable' info + $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } - $v_temp_zip->privCloseFd(); - $this->privCloseFd(); - @unlink($this->zipname); + // ----- Zip file comment + $v_comment = ''; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } - PclZipUtilRename($v_zip_temp_name, $this->zipname); - - unset($v_temp_zip); - } - - else if ($v_central_dir['entries'] != 0) { - $this->privCloseFd(); + // ----- Calculate the size of the central header + $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset; - if (($v_result = $this->privOpenFd('wb')) != 1) { - return $v_result; - } + // ----- Create the central dir footer + if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) { + // ----- Reset the file list + unset($v_header_list); + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); - if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) { - return $v_result; - } + // ----- Return + return $v_result; + } - $this->privCloseFd(); - } + // ----- Close + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Destroy the temporary archive + unset($v_temp_zip); + } + + // ----- Remove every files : reset the file + else if ($v_central_dir['entries'] != 0) { + $this->privCloseFd(); - return $v_result; -} + if (($v_result = $this->privOpenFd('wb')) != 1) { + return $v_result; + } -function privDirCheck($p_dir, $p_is_dir=false) -{ - $v_result = 1; + if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) { + return $v_result; + } + $this->privCloseFd(); + } - if (($p_is_dir) && (substr($p_dir, -1)=='/')) - { - $p_dir = substr($p_dir, 0, strlen($p_dir)-1); + // ----- Return + return $v_result; } - - if ((is_dir($p_dir)) || ($p_dir == "")) + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDirCheck() + // Description : + // Check if a directory exists, if not it creates it and all the parents directory + // which may be useful. + // Parameters : + // $p_dir : Directory path to check. + // Return Values : + // 1 : OK + // -1 : Unable to create directory + // -------------------------------------------------------------------------------- + function privDirCheck($p_dir, $p_is_dir=false) { - return 1; - } + $v_result = 1; - $p_parent_dir = dirname($p_dir); - if ($p_parent_dir != $p_dir) - { - if ($p_parent_dir != "") + // ----- Remove the final '/' + if (($p_is_dir) && (substr($p_dir, -1)=='/')) + { + $p_dir = substr($p_dir, 0, strlen($p_dir)-1); + } + + // ----- Check the directory availability + if ((is_dir($p_dir)) || ($p_dir == "")) { - if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) + return 1; + } + + // ----- Extract parent directory + $p_parent_dir = dirname($p_dir); + + // ----- Just a check + if ($p_parent_dir != $p_dir) + { + // ----- Look for parent directory + if ($p_parent_dir != "") { - return $v_result; + if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) + { + return $v_result; + } } } + + // ----- Create the directory + if (!@mkdir($p_dir, 0777)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Return + return $v_result; } + // -------------------------------------------------------------------------------- - if (!@mkdir($p_dir, 0777)) + // -------------------------------------------------------------------------------- + // Function : privMerge() + // Description : + // If $p_archive_to_add does not exist, the function exit with a success result. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privMerge(&$p_archive_to_add) { - PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'"); + $v_result=1; - return PclZip::errorCode(); - } + // ----- Look if the archive_to_add exists + if (!is_file($p_archive_to_add->zipname)) + { - return $v_result; -} + // ----- Nothing to merge, so merge is a success + $v_result = 1; -function privMerge(&$p_archive_to_add) -{ - $v_result=1; + // ----- Return + return $v_result; + } - if (!is_file($p_archive_to_add->zipname)) - { + // ----- Look if the archive exists + if (!is_file($this->zipname)) + { - $v_result = 1; + // ----- Do a duplicate + $v_result = $this->privDuplicate($p_archive_to_add->zipname); - return $v_result; - } + // ----- Return + return $v_result; + } - if (!is_file($this->zipname)) - { + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Return + return $v_result; + } - $v_result = $this->privDuplicate($p_archive_to_add->zipname); + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + return $v_result; + } - return $v_result; - } + // ----- Go to beginning of File + @rewind($this->zip_fd); - if (($v_result=$this->privOpenFd('rb')) != 1) - { - return $v_result; - } + // ----- Open the archive_to_add file + if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1) + { + $this->privCloseFd(); - $v_central_dir = array(); - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) - { - $this->privCloseFd(); - return $v_result; - } + // ----- Return + return $v_result; + } - @rewind($this->zip_fd); + // ----- Read the central directory informations + $v_central_dir_to_add = array(); + if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); - if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1) - { - $this->privCloseFd(); + return $v_result; + } - return $v_result; - } + // ----- Go to beginning of File + @rewind($p_archive_to_add->zip_fd); - $v_central_dir_to_add = array(); - if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) - { - $this->privCloseFd(); - $p_archive_to_add->privCloseFd(); + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; - return $v_result; - } + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); - @rewind($p_archive_to_add->zip_fd); + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); - $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + // ----- Return + return PclZip::errorCode(); + } - if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) - { - $this->privCloseFd(); - $p_archive_to_add->privCloseFd(); + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); + // ----- Copy the files from the archive_to_add into the temporary file + $v_size = $v_central_dir_to_add['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } - return PclZip::errorCode(); - } + // ----- Store the offset of the central dir + $v_offset = @ftell($v_zip_temp_fd); - $v_size = $v_central_dir['offset']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = fread($this->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } - $v_size = $v_central_dir_to_add['offset']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + // ----- Copy the block of file headers from the archive_to_add + $v_size = $v_central_dir_to_add['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } - $v_offset = @ftell($v_zip_temp_fd); + // ----- Merge the file comments + $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment']; - $v_size = $v_central_dir['size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($this->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + // ----- Calculate the size of the (new) central header + $v_size = @ftell($v_zip_temp_fd)-$v_offset; - $v_size = $v_central_dir_to_add['size']; - while ($v_size != 0) - { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size); - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; - } + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive fd + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; - $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment']; + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + @fclose($v_zip_temp_fd); + $this->zip_fd = null; - $v_size = @ftell($v_zip_temp_fd)-$v_offset; + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; + } - $v_swap = $this->zip_fd; - $this->zip_fd = $v_zip_temp_fd; - $v_zip_temp_fd = $v_swap; + // ----- Swap back the file descriptor + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; - if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) - { + // ----- Close $this->privCloseFd(); $p_archive_to_add->privCloseFd(); + + // ----- Close the temporary file @fclose($v_zip_temp_fd); - $this->zip_fd = null; - unset($v_header_list); + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + // ----- Return return $v_result; } + // -------------------------------------------------------------------------------- - $v_swap = $this->zip_fd; - $this->zip_fd = $v_zip_temp_fd; - $v_zip_temp_fd = $v_swap; + // -------------------------------------------------------------------------------- + // Function : privDuplicate() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDuplicate($p_archive_filename) + { + $v_result=1; - $this->privCloseFd(); - $p_archive_to_add->privCloseFd(); + // ----- Look if the $p_archive_filename exists + if (!is_file($p_archive_filename)) + { - @fclose($v_zip_temp_fd); + // ----- Nothing to duplicate, so duplicate is a success. + $v_result = 1; - @unlink($this->zipname); + // ----- Return + return $v_result; + } - PclZipUtilRename($v_zip_temp_name, $this->zipname); + // ----- Open the zip file + if (($v_result=$this->privOpenFd('wb')) != 1) + { + // ----- Return + return $v_result; + } - return $v_result; -} + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) + { + $this->privCloseFd(); -function privDuplicate($p_archive_filename) -{ - $v_result=1; + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode'); - if (!is_file($p_archive_filename)) - { + // ----- Return + return PclZip::errorCode(); + } - $v_result = 1; + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = filesize($p_archive_filename); + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } - return $v_result; - } + // ----- Close + $this->privCloseFd(); - if (($v_result=$this->privOpenFd('wb')) != 1) - { + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Return return $v_result; } + // -------------------------------------------------------------------------------- - if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) + // -------------------------------------------------------------------------------- + // Function : privErrorLog() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privErrorLog($p_error_code=0, $p_error_string='') { - $this->privCloseFd(); - - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode'); - - return PclZip::errorCode(); + if (PCLZIP_ERROR_EXTERNAL == 1) { + PclError($p_error_code, $p_error_string); + } + else { + $this->error_code = $p_error_code; + $this->error_string = $p_error_string; + } } + // -------------------------------------------------------------------------------- - $v_size = filesize($p_archive_filename); - while ($v_size != 0) + // -------------------------------------------------------------------------------- + // Function : privErrorReset() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privErrorReset() { - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = fread($v_zip_temp_fd, $v_read_size); - @fwrite($this->zip_fd, $v_buffer, $v_read_size); - $v_size -= $v_read_size; + if (PCLZIP_ERROR_EXTERNAL == 1) { + PclErrorReset(); + } + else { + $this->error_code = 0; + $this->error_string = ''; + } } + // -------------------------------------------------------------------------------- - $this->privCloseFd(); - - @fclose($v_zip_temp_fd); - - return $v_result; -} + // -------------------------------------------------------------------------------- + // Function : privDisableMagicQuotes() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDisableMagicQuotes() + { + $v_result=1; -function privErrorLog($p_error_code=0, $p_error_string='') -{ - if (PCLZIP_ERROR_EXTERNAL == 1) { - PclError($p_error_code, $p_error_string); - } - else { - $this->error_code = $p_error_code; - $this->error_string = $p_error_string; - } -} + // ----- Look if function exists + if ( (!function_exists("get_magic_quotes_runtime")) + || (!function_exists("set_magic_quotes_runtime"))) { + return $v_result; + } -function privErrorReset() -{ - if (PCLZIP_ERROR_EXTERNAL == 1) { - PclErrorReset(); - } - else { - $this->error_code = 0; - $this->error_string = ''; - } -} + // ----- Look if already done + if ($this->magic_quotes_status != -1) { + return $v_result; + } -function privDisableMagicQuotes() -{ - $v_result=1; + // ----- Get and memorize the magic_quote value + $this->magic_quotes_status = @get_magic_quotes_runtime(); - if ( (!function_exists("get_magic_quotes_runtime")) - || (!function_exists("set_magic_quotes_runtime"))) { - return $v_result; -} + // ----- Disable magic_quotes + if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime(0); + } - if ($this->magic_quotes_status != -1) { + // ----- Return return $v_result; -} - -$this->magic_quotes_status = @get_magic_quotes_runtime(); + } + // -------------------------------------------------------------------------------- -if ($this->magic_quotes_status == 1) { - @set_magic_quotes_runtime(0); -} + // -------------------------------------------------------------------------------- + // Function : privSwapBackMagicQuotes() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privSwapBackMagicQuotes() + { + $v_result=1; - return $v_result; -} + // ----- Look if function exists + if ( (!function_exists("get_magic_quotes_runtime")) + || (!function_exists("set_magic_quotes_runtime"))) { + return $v_result; + } -function privSwapBackMagicQuotes() -{ - $v_result=1; + // ----- Look if something to do + if ($this->magic_quotes_status != -1) { + return $v_result; + } - if ( (!function_exists("get_magic_quotes_runtime")) - || (!function_exists("set_magic_quotes_runtime"))) { - return $v_result; -} + // ----- Swap back magic_quotes + if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime($this->magic_quotes_status); + } - if ($this->magic_quotes_status != -1) { + // ----- Return return $v_result; -} - -if ($this->magic_quotes_status == 1) { - @set_magic_quotes_runtime($this->magic_quotes_status); -} - - return $v_result; -} - -} - -function PclZipUtilPathReduction($p_dir) -{ - $v_result = ""; + } + // -------------------------------------------------------------------------------- - if ($p_dir != "") { - $v_list = explode("/", $p_dir); + } + // End of class + // -------------------------------------------------------------------------------- - $v_skip = 0; - for ($i=sizeof($v_list)-1; $i>=0; $i--) { - if ($v_list[$i] == ".") { - } - else if ($v_list[$i] == "..") { - $v_skip++; + // -------------------------------------------------------------------------------- + // Function : PclZipUtilPathReduction() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function PclZipUtilPathReduction($p_dir) + { + $v_result = ""; + + // ----- Look for not empty path + if ($p_dir != "") { + // ----- Explode path by directory names + $v_list = explode("/", $p_dir); + + // ----- Study directories from last to first + $v_skip = 0; + for ($i=sizeof($v_list)-1; $i>=0; $i--) { + // ----- Look for current path + if ($v_list[$i] == ".") { + // ----- Ignore this directory + // Should be the first $i=0, but no check is done + } + else if ($v_list[$i] == "..") { + $v_skip++; + } + else if ($v_list[$i] == "") { + // ----- First '/' i.e. root slash + if ($i == 0) { + $v_result = "/".$v_result; + if ($v_skip > 0) { + // ----- It is an invalid path, so the path is not modified + // TBC + $v_result = $p_dir; + $v_skip = 0; + } + } + // ----- Last '/' i.e. indicates a directory + else if ($i == (sizeof($v_list)-1)) { + $v_result = $v_list[$i]; + } + // ----- Double '/' inside the path + else { + // ----- Ignore only the double '//' in path, + // but not the first and last '/' + } + } + else { + // ----- Look for item to skip + if ($v_skip > 0) { + $v_skip--; + } + else { + $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); + } + } } - else if ($v_list[$i] == "") { - if ($i == 0) { - $v_result = "/".$v_result; + + // ----- Look for skip if ($v_skip > 0) { - $v_result = $p_dir; - $v_skip = 0; - } - } - else if ($i == (sizeof($v_list)-1)) { - $v_result = $v_list[$i]; - } - else { - } - } - else { - if ($v_skip > 0) { - $v_skip--; - } - else { - $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); - } + while ($v_skip > 0) { + $v_result = '../'.$v_result; + $v_skip--; + } } } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilPathInclusion() + // Description : + // This function indicates if the path $p_path is under the $p_dir tree. Or, + // said in an other way, if the file or sub-dir $p_path is inside the dir + // $p_dir. + // The function indicates also if the path is exactly the same as the dir. + // This function supports path with duplicated '/' like '//', but does not + // support '.' or '..' statements. + // Parameters : + // Return Values : + // 0 if $p_path is not inside directory $p_dir + // 1 if $p_path is inside directory $p_dir + // 2 if $p_path is exactly the same as $p_dir + // -------------------------------------------------------------------------------- + function PclZipUtilPathInclusion($p_dir, $p_path) + { + $v_result = 1; - if ($v_skip > 0) { - while ($v_skip > 0) { - $v_result = '../'.$v_result; - $v_skip--; - } + // ----- Look for path beginning by ./ + if ( ($p_dir == '.') + || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) { + $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1); + } + if ( ($p_path == '.') + || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) { + $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1); } - } - return $v_result; -} + // ----- Explode dir and path by directory separator + $v_list_dir = explode("/", $p_dir); + $v_list_dir_size = sizeof($v_list_dir); + $v_list_path = explode("/", $p_path); + $v_list_path_size = sizeof($v_list_path); -function PclZipUtilPathInclusion($p_dir, $p_path) -{ - $v_result = 1; - - if ( ($p_dir == '.') - || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) { - $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1); - } - if ( ($p_path == '.') - || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) { - $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1); - } + // ----- Study directories paths + $i = 0; + $j = 0; + while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) { - $v_list_dir = explode("/", $p_dir); - $v_list_dir_size = sizeof($v_list_dir); - $v_list_path = explode("/", $p_path); - $v_list_path_size = sizeof($v_list_path); + // ----- Look for empty dir (path reduction) + if ($v_list_dir[$i] == '') { + $i++; + continue; + } + if ($v_list_path[$j] == '') { + $j++; + continue; + } - $i = 0; - $j = 0; - while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) { + // ----- Compare the items + if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) { + $v_result = 0; + } - if ($v_list_dir[$i] == '') { + // ----- Next items $i++; - continue; - } - if ($v_list_path[$j] == '') { $j++; - continue; - } - - if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) { - $v_result = 0; } - $i++; - $j++; - } - - if ($v_result) { - while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; - while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; + // ----- Look if everything seems to be the same + if ($v_result) { + // ----- Skip all the empty items + while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; + while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; - if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { - $v_result = 2; - } - else if ($i < $v_list_dir_size) { - $v_result = 0; + if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { + // ----- There are exactly the same + $v_result = 2; + } + else if ($i < $v_list_dir_size) { + // ----- The path is shorter than the dir + $v_result = 0; + } } - } - - return $v_result; -} - -function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0) -{ - $v_result = 1; - if ($p_mode==0) + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilCopyBlock() + // Description : + // Parameters : + // $p_mode : read/write compression mode + // 0 : src & dest normal + // 1 : src gzip, dest normal + // 2 : src normal, dest gzip + // 3 : src & dest gzip + // Return Values : + // -------------------------------------------------------------------------------- + function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0) { - while ($p_size != 0) + $v_result = 1; + + if ($p_mode==0) { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($p_src, $v_read_size); - @fwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } } - } - else if ($p_mode==1) - { - while ($p_size != 0) + else if ($p_mode==1) { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @gzread($p_src, $v_read_size); - @fwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } } - } - else if ($p_mode==2) - { - while ($p_size != 0) + else if ($p_mode==2) { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @fread($p_src, $v_read_size); - @gzwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } } - } - else if ($p_mode==3) - { - while ($p_size != 0) + else if ($p_mode==3) { - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); - $v_buffer = @gzread($p_src, $v_read_size); - @gzwrite($p_dest, $v_buffer, $v_read_size); - $p_size -= $v_read_size; + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } } - } - - return $v_result; -} -function PclZipUtilRename($p_src, $p_dest) -{ - $v_result = 1; + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilRename() + // Description : + // This function tries to do a simple rename() function. If it fails, it + // tries to copy the $p_src file in a new $p_dest file and then unlink the + // first one. + // Parameters : + // $p_src : Old filename + // $p_dest : New filename + // Return Values : + // 1 on success, 0 on failure. + // -------------------------------------------------------------------------------- + function PclZipUtilRename($p_src, $p_dest) + { + $v_result = 1; - if (!@rename($p_src, $p_dest)) { + // ----- Try to rename the files + if (!@rename($p_src, $p_dest)) { - if (!@copy($p_src, $p_dest)) { - $v_result = 0; - } - else if (!@unlink($p_src)) { - $v_result = 0; + // ----- Try to copy & unlink the src + if (!@copy($p_src, $p_dest)) { + $v_result = 0; + } + else if (!@unlink($p_src)) { + $v_result = 0; + } } - } - return $v_result; -} + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilOptionText() + // Description : + // Translate option value in text. Mainly for debug purpose. + // Parameters : + // $p_option : the option value. + // Return Values : + // The option text value. + // -------------------------------------------------------------------------------- + function PclZipUtilOptionText($p_option) + { + + $v_list = get_defined_constants(); + for (reset($v_list); $v_key = key($v_list); next($v_list)) { + $v_prefix = substr($v_key, 0, 10); + if (( ($v_prefix == 'PCLZIP_OPT') + || ($v_prefix == 'PCLZIP_CB_') + || ($v_prefix == 'PCLZIP_ATT')) + && ($v_list[$v_key] == $p_option)) { + return $v_key; + } + } + + $v_result = 'Unknown'; -function PclZipUtilOptionText($p_option) -{ - - $v_list = get_defined_constants(); - for (reset($v_list); $v_key = key($v_list); next($v_list)) { - $v_prefix = substr($v_key, 0, 10); - if (( ($v_prefix == 'PCLZIP_OPT') - || ($v_prefix == 'PCLZIP_CB_') - || ($v_prefix == 'PCLZIP_ATT')) - && ($v_list[$v_key] == $p_option)) { - return $v_key; + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilTranslateWinPath() + // Description : + // Translate windows path by replacing '\' by '/' and optionally removing + // drive letter. + // Parameters : + // $p_path : path to translate. + // $p_remove_disk_letter : true | false + // Return Values : + // The path translated. + // -------------------------------------------------------------------------------- + function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true) + { + if (stristr(php_uname(), 'windows')) { + // ----- Look for potential disk letter + if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { + $p_path = substr($p_path, $v_position+1); + } + // ----- Change potential windows directory separator + if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { + $p_path = strtr($p_path, '\\', '/'); + } } + return $p_path; } - - $v_result = 'Unknown'; + // -------------------------------------------------------------------------------- - return $v_result; -} -function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true) -{ - if (stristr(php_uname(), 'windows')) { - if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { - $p_path = substr($p_path, $v_position+1); - } - if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { - $p_path = strtr($p_path, '\\', '/'); - } - } - return $p_path; -} ?> diff --git a/admin/include/uploadify/cancel.png b/admin/include/uploadify/cancel.png new file mode 100644 index 000000000..1c7d627c3 Binary files /dev/null and b/admin/include/uploadify/cancel.png differ diff --git a/admin/include/uploadify/jquery.uploadify.v2.1.0.min.js b/admin/include/uploadify/jquery.uploadify.v2.1.0.min.js new file mode 100644 index 000000000..04592ffec --- /dev/null +++ b/admin/include/uploadify/jquery.uploadify.v2.1.0.min.js @@ -0,0 +1,26 @@ +/* +Uploadify v2.1.0 +Release Date: August 24, 2009 + +Copyright (c) 2009 Ronnie Garcia, Travis Nickels + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +if(jQuery){(function(a){a.extend(a.fn,{uploadify:function(b){a(this).each(function(){settings=a.extend({id:a(this).attr("id"),uploader:"uploadify.swf",script:"uploadify.php",expressInstall:null,folder:"",height:30,width:110,cancelImg:"cancel.png",wmode:"opaque",scriptAccess:"sameDomain",fileDataName:"Filedata",method:"POST",queueSizeLimit:999,simUploadLimit:1,queueID:false,displayData:"percentage",onInit:function(){},onSelect:function(){},onQueueFull:function(){},onCheck:function(){},onCancel:function(){},onError:function(){},onProgress:function(){},onComplete:function(){},onAllComplete:function(){}},b);var e=location.pathname;e=e.split("/");e.pop();e=e.join("/")+"/";var f={};f.uploadifyID=settings.id;f.pagepath=e;if(settings.buttonImg){f.buttonImg=escape(settings.buttonImg)}if(settings.buttonText){f.buttonText=escape(settings.buttonText)}if(settings.rollover){f.rollover=true}f.script=settings.script;f.folder=escape(settings.folder);if(settings.scriptData){var g="";for(var d in settings.scriptData){g+="&"+d+"="+settings.scriptData[d]}f.scriptData=escape(g.substr(1))}f.width=settings.width;f.height=settings.height;f.wmode=settings.wmode;f.method=settings.method;f.queueSizeLimit=settings.queueSizeLimit;f.simUploadLimit=settings.simUploadLimit;if(settings.hideButton){f.hideButton=true}if(settings.fileDesc){f.fileDesc=settings.fileDesc}if(settings.fileExt){f.fileExt=settings.fileExt}if(settings.multi){f.multi=true}if(settings.auto){f.auto=true}if(settings.sizeLimit){f.sizeLimit=settings.sizeLimit}if(settings.checkScript){f.checkScript=settings.checkScript}if(settings.fileDataName){f.fileDataName=settings.fileDataName}if(settings.queueID){f.queueID=settings.queueID}if(settings.onInit()!==false){a(this).css("display","none");a(this).after('
');swfobject.embedSWF(settings.uploader,settings.id+"Uploader",settings.width,settings.height,"9.0.24",settings.expressInstall,f,{quality:"high",wmode:settings.wmode,allowScriptAccess:settings.scriptAccess});if(settings.queueID==false){a("#"+a(this).attr("id")+"Uploader").after('
')}}if(typeof(settings.onOpen)=="function"){a(this).bind("uploadifyOpen",settings.onOpen)}a(this).bind("uploadifySelect",{action:settings.onSelect,queueID:settings.queueID},function(j,h,i){if(j.data.action(j,h,i)!==false){var k=Math.round(i.size/1024*100)*0.01;var l="KB";if(k>1000){k=Math.round(k*0.001*100)*0.01;l="MB"}var m=k.toString().split(".");if(m.length>1){k=m[0]+"."+m[1].substr(0,2)}else{k=m[0]}if(i.name.length>20){fileName=i.name.substr(0,20)+"..."}else{fileName=i.name}queue="#"+a(this).attr("id")+"Queue";if(j.data.queueID){queue="#"+j.data.queueID}a(queue).append('
'+fileName+" ("+k+l+')
')}});if(typeof(settings.onSelectOnce)=="function"){a(this).bind("uploadifySelectOnce",settings.onSelectOnce)}a(this).bind("uploadifyQueueFull",{action:settings.onQueueFull},function(h,i){if(h.data.action(h,i)!==false){alert("The queue is full. The max size is "+i+".")}});a(this).bind("uploadifyCheckExist",{action:settings.onCheck},function(m,l,k,j,o){var i=new Object();i=k;i.folder=e+j;if(o){for(var h in k){var n=h}}a.post(l,i,function(r){for(var p in r){if(m.data.action(m,l,k,j,o)!==false){var q=confirm("Do you want to replace the file "+r[p]+"?");if(!q){document.getElementById(a(m.target).attr("id")+"Uploader").cancelFileUpload(p,true,true)}}}if(o){document.getElementById(a(m.target).attr("id")+"Uploader").startFileUpload(n,true)}else{document.getElementById(a(m.target).attr("id")+"Uploader").startFileUpload(null,true)}},"json")});a(this).bind("uploadifyCancel",{action:settings.onCancel},function(l,h,k,m,j){if(l.data.action(l,h,k,m,j)!==false){var i=(j==true)?0:250;a("#"+a(this).attr("id")+h).fadeOut(i,function(){a(this).remove()})}});if(typeof(settings.onClearQueue)=="function"){a(this).bind("uploadifyClearQueue",settings.onClearQueue)}var c=[];a(this).bind("uploadifyError",{action:settings.onError},function(l,h,k,j){if(l.data.action(l,h,k,j)!==false){var i=new Array(h,k,j);c.push(i);a("#"+a(this).attr("id")+h+" .percentage").text(" - "+j.type+" Error");a("#"+a(this).attr("id")+h).addClass("uploadifyError")}});a(this).bind("uploadifyProgress",{action:settings.onProgress,toDisplay:settings.displayData},function(j,h,i,k){if(j.data.action(j,h,i,k)!==false){a("#"+a(this).attr("id")+h+"ProgressBar").css("width",k.percentage+"%");if(j.data.toDisplay=="percentage"){displayData=" - "+k.percentage+"%"}if(j.data.toDisplay=="speed"){displayData=" - "+k.speed+"KB/s"}if(j.data.toDisplay==null){displayData=" "}a("#"+a(this).attr("id")+h+" .percentage").text(displayData)}});a(this).bind("uploadifyComplete",{action:settings.onComplete},function(k,h,j,i,l){if(k.data.action(k,h,j,unescape(i),l)!==false){a("#"+a(this).attr("id")+h+" .percentage").text(" - Completed");a("#"+a(this).attr("id")+h).fadeOut(250,function(){a(this).remove()})}});if(typeof(settings.onAllComplete)=="function"){a(this).bind("uploadifyAllComplete",{action:settings.onAllComplete},function(h,i){if(h.data.action(h,i)!==false){c=[]}})}})},uploadifySettings:function(f,j,c){var g=false;a(this).each(function(){if(f=="scriptData"&&j!=null){if(c){var i=j}else{var i=a.extend(settings.scriptData,j)}var l="";for(var k in i){l+="&"+k+"="+escape(i[k])}j=l.substr(1)}g=document.getElementById(a(this).attr("id")+"Uploader").updateSettings(f,j)});if(j==null){if(f=="scriptData"){var b=unescape(g).split("&");var e=new Object();for(var d=0;d + is released under the MIT License +*/ +var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y0){for(var af=0;af0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad'}}aa.outerHTML='"+af+"";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab \ No newline at end of file diff --git a/admin/include/uploadify/uploadify.swf b/admin/include/uploadify/uploadify.swf new file mode 100644 index 000000000..4d27952f5 Binary files /dev/null and b/admin/include/uploadify/uploadify.swf differ diff --git a/admin/photos_add.php b/admin/photos_add.php new file mode 100644 index 000000000..b076cdf29 --- /dev/null +++ b/admin/photos_add.php @@ -0,0 +1,199 @@ + array( + 'default' => true, + 'can_be_null' => false, + ), + + 'websize_maxwidth' => array( + 'default' => 800, + 'min' => 100, + 'max' => 1600, + 'pattern' => '/^\d+$/', + 'can_be_null' => true, + 'error_message' => 'The websize maximum width must be a number between %d and %d', + ), + + 'websize_maxheight' => array( + 'default' => 600, + 'min' => 100, + 'max' => 1200, + 'pattern' => '/^\d+$/', + 'can_be_null' => true, + 'error_message' => 'The websize maximum height must be a number between %d and %d', + ), + + 'websize_quality' => array( + 'default' => 95, + 'min' => 50, + 'max' => 100, + 'pattern' => '/^\d+$/', + 'can_be_null' => false, + 'error_message' => 'The websize image quality must be a number between %d and %d', + ), + + 'thumb_maxwidth' => array( + 'default' => 128, + 'min' => 50, + 'max' => 300, + 'pattern' => '/^\d+$/', + 'can_be_null' => false, + 'error_message' => 'The thumbnail maximum width must be a number between %d and %d', + ), + + 'thumb_maxheight' => array( + 'default' => 96, + 'min' => 50, + 'max' => 300, + 'pattern' => '/^\d+$/', + 'can_be_null' => false, + 'error_message' => 'The thumbnail maximum height must be a number between %d and %d', + ), + + 'thumb_quality' => array( + 'default' => 95, + 'min' => 50, + 'max' => 100, + 'pattern' => '/^\d+$/', + 'can_be_null' => false, + 'error_message' => 'The thumbnail image quality must be a number between %d and %d', + ), + ); + +$inserts = array(); + +foreach ($upload_form_config as $param_shortname => $param) +{ + $param_name = 'upload_form_'.$param_shortname; + + if (!isset($conf[$param_name])) + { + $param_value = boolean_to_string($param['default']); + + array_push( + $inserts, + array( + 'param' => $param_name, + 'value' => $param_value, + ) + ); + $conf[$param_name] = $param_value; + } +} + +if (count($inserts) > 0) +{ + mass_inserts( + CONFIG_TABLE, + array_keys($inserts[0]), + $inserts + ); +} + +// +-----------------------------------------------------------------------+ +// | Tabs | +// +-----------------------------------------------------------------------+ + +$tabs = array( + array( + 'code' => 'direct', + 'label' => 'Upload Photos', + ), + array( + 'code' => 'settings', + 'label' => 'Settings', + ) + ); + +$tab_codes = array_map( + create_function('$a', 'return $a["code"];'), + $tabs + ); + +if (isset($_GET['section']) and in_array($_GET['section'], $tab_codes)) +{ + $page['tab'] = $_GET['section']; +} +else +{ + $page['tab'] = $tabs[0]['code']; +} + +$tabsheet = new tabsheet(); +foreach ($tabs as $tab) +{ + $tabsheet->add( + $tab['code'], + l10n($tab['label']), + PHOTOS_ADD_BASE_URL.'&section='.$tab['code'] + ); +} +$tabsheet->select($page['tab']); +$tabsheet->assign(); + +// +-----------------------------------------------------------------------+ +// | template init | +// +-----------------------------------------------------------------------+ + +$template->set_filenames( + array( + 'plugin_admin_content' => 'photos_add_'.$page['tab'].'.tpl' + ) + ); + +// $template->append( +// 'head_elements', +// ''."\n" +// ); + +// +-----------------------------------------------------------------------+ +// | Load the tab | +// +-----------------------------------------------------------------------+ + +include(PHPWG_ROOT_PATH.'admin/photos_add_'.$page['tab'].'.php'); +?> \ No newline at end of file diff --git a/admin/photos_add_direct.php b/admin/photos_add_direct.php new file mode 100644 index 000000000..4fceb6b12 --- /dev/null +++ b/admin/photos_add_direct.php @@ -0,0 +1,488 @@ + $user['id'], + 'element_id' => $image_id, + ) + ); + } + mass_inserts( + CADDIE_TABLE, + array_keys($inserts[0]), + $inserts + ); + + redirect(get_root_url().'admin.php?page=element_set&cat=caddie'); +} + +// +-----------------------------------------------------------------------+ +// | process form | +// +-----------------------------------------------------------------------+ + +if (isset($_POST['submit_upload'])) +{ +// echo '
POST'."\n"; print_r($_POST); echo '
'; +// echo '
FILES'."\n"; print_r($_FILES); echo '
'; +// echo '
SESSION'."\n"; print_r($_SESSION); echo '
'; +// exit(); + + $category_id = null; + if ('existing' == $_POST['category_type']) + { + $category_id = $_POST['category']; + } + elseif ('new' == $_POST['category_type']) + { + $output_create = create_virtual_category( + $_POST['category_name'], + (0 == $_POST['category_parent'] ? null : $_POST['category_parent']) + ); + + $category_id = $output_create['id']; + + if (isset($output_create['error'])) + { + array_push($page['errors'], $output_create['error']); + } + else + { + $category_name = get_cat_display_name_from_id($category_id, 'admin.php?page=cat_modify&cat_id='); + // information + array_push( + $page['infos'], + sprintf( + l10n('Category "%s" has been added'), + ''.$category_name.'' + ) + ); + // TODO: add the onclick="window.open(this.href); return false;" + // attribute with jQuery on upload.tpl side for href containing + // "cat_modify" + } + } + + $image_ids = array(); + + if (isset($_FILES) and !empty($_FILES['image_upload'])) + { + $starttime = get_moment(); + + foreach ($_FILES['image_upload']['error'] as $idx => $error) + { + if (UPLOAD_ERR_OK == $error) + { + $images_to_add = array(); + + $extension = pathinfo($_FILES['image_upload']['name'][$idx], PATHINFO_EXTENSION); + if ('zip' == strtolower($extension)) + { + $upload_dir = PHPWG_ROOT_PATH.'upload/buffer'; + prepare_directory($upload_dir); + + $temporary_archive_name = date('YmdHis').'-'.generate_key(10); + $archive_path = $upload_dir.'/'.$temporary_archive_name.'.zip'; + + move_uploaded_file( + $_FILES['image_upload']['tmp_name'][$idx], + $archive_path + ); + + define('PCLZIP_TEMPORARY_DIR', $upload_dir.'/'); + include(PHPWG_ROOT_PATH.'admin/include/pclzip.lib.php'); + $zip = new PclZip($archive_path); + if ($list = $zip->listContent()) + { + $indexes_to_extract = array(); + + foreach ($list as $node) + { + if (1 == $node['folder']) + { + continue; + } + + if (is_valid_image_extension(pathinfo($node['filename'], PATHINFO_EXTENSION))) + { + array_push($indexes_to_extract, $node['index']); + + array_push( + $images_to_add, + array( + 'source_filepath' => $upload_dir.'/'.$temporary_archive_name.'/'.$node['filename'], + 'original_filename' => basename($node['filename']), + ) + ); + } + } + + if (count($indexes_to_extract) > 0) + { + $zip->extract( + PCLZIP_OPT_PATH, $upload_dir.'/'.$temporary_archive_name, + PCLZIP_OPT_BY_INDEX, $indexes_to_extract, + PCLZIP_OPT_ADD_TEMP_FILE_ON + ); + } + } + } + elseif (is_valid_image_extension($extension)) + { + array_push( + $images_to_add, + array( + 'source_filepath' => $_FILES['image_upload']['tmp_name'][$idx], + 'original_filename' => $_FILES['image_upload']['name'][$idx], + ) + ); + } + + foreach ($images_to_add as $image_to_add) + { + $image_id = add_uploaded_file( + $image_to_add['source_filepath'], + $image_to_add['original_filename'], + array($category_id), + $_POST['level'] + ); + + array_push($image_ids, $image_id); + + // TODO: if $image_id is not an integer, something went wrong + } + } + } + + $endtime = get_moment(); + $elapsed = ($endtime - $starttime) * 1000; + // printf('%.2f ms', $elapsed); + + } // if (!empty($_FILES)) + + if (isset($_POST['upload_id'])) + { + // we're on a multiple upload, with uploadify and so on + $image_ids = $_SESSION['uploads'][ $_POST['upload_id'] ]; + + associate_images_to_categories( + $image_ids, + array($category_id) + ); + + $query = ' +UPDATE '.IMAGES_TABLE.' + SET level = '.$_POST['level'].' + WHERE id IN ('.implode(', ', $image_ids).') +;'; + pwg_query($query); + + invalidate_user_cache(); + } + + $page['thumbnails'] = array(); + foreach ($image_ids as $image_id) + { + // we could return the list of properties from the add_uploaded_file + // function, but I like the "double check". And it costs nothing + // compared to the upload process. + $thumbnail = array(); + + $query = ' +SELECT + file, + path, + tn_ext + FROM '.IMAGES_TABLE.' + WHERE id = '.$image_id.' +;'; + $image_infos = mysql_fetch_assoc(pwg_query($query)); + + $thumbnail['file'] = $image_infos['file']; + + $thumbnail['src'] = get_thumbnail_location( + array( + 'path' => $image_infos['path'], + 'tn_ext' => $image_infos['tn_ext'], + ) + ); + + // TODO: when implementing this plugin in Piwigo core, we should have + // a function get_image_name($name, $file) (if name is null, then + // compute a temporary name from filename) that would be also used in + // picture.php. UPDATE: in fact, "get_name_from_file($file)" already + // exists and is used twice (element_set_unit + comments, but not in + // picture.php I don't know why) with the same pattern if + // (empty($name)) {$name = get_name_from_file($file)}, a clean + // function get_image_name($name, $file) would be better + $thumbnail['title'] = get_name_from_file($image_infos['file']); + + $thumbnail['link'] = PHPWG_ROOT_PATH.'admin.php?page=picture_modify' + .'&image_id='.$image_id + .'&cat_id='.$category_id + ; + + array_push($page['thumbnails'], $thumbnail); + } + + if (!empty($page['thumbnails'])) + { + array_push( + $page['infos'], + sprintf( + l10n('%d photos uploaded'), + count($page['thumbnails']) + ) + ); + + if (0 != $_POST['level']) + { + array_push( + $page['infos'], + sprintf( + l10n('Privacy level set to "%s"'), + l10n( + sprintf('Level %d', $_POST['level']) + ) + ) + ); + } + + if ('existing' == $_POST['category_type']) + { + $query = ' +SELECT + COUNT(*) + FROM '.IMAGE_CATEGORY_TABLE.' + WHERE category_id = '.$category_id.' +;'; + list($count) = mysql_fetch_row(pwg_query($query)); + $category_name = get_cat_display_name_from_id($category_id, 'admin.php?page=cat_modify&cat_id='); + + // information + array_push( + $page['infos'], + sprintf( + l10n('Category "%s" now contains %d photos'), + ''.$category_name.'', + $count + ) + ); + } + + $page['batch_link'] = PHOTOS_ADD_BASE_URL.'&batch='.implode(',', $image_ids); + } +} + +// +-----------------------------------------------------------------------+ +// | template init | +// +-----------------------------------------------------------------------+ + +$uploadify_path = PHPWG_ROOT_PATH.'admin/include/uploadify'; + +$template->assign( + array( + 'F_ADD_ACTION'=> PHOTOS_ADD_BASE_URL, + 'uploadify_path' => $uploadify_path, + ) + ); + +$upload_modes = array('html', 'multiple'); + +$upload_mode = 'multiple'; +$upload_switch = 'html'; +if (isset($_GET['upload_mode']) and in_array($_GET['upload_mode'], $upload_modes)) +{ + $index_of_upload_mode = array_flip($upload_modes); + $upload_mode_index = $index_of_upload_mode[ $_GET['upload_mode'] ]; + + $upload_mode = $_GET['upload_mode']; + $upload_switch = $upload_modes[ ($upload_mode_index + 1) % 2 ]; +} + +$template->assign( + array( + 'upload_mode' => $upload_mode, + 'switch_url' => PHOTOS_ADD_BASE_URL.'&upload_mode='.$upload_switch, + 'upload_id' => md5(rand()), + 'session_id' => session_id(), + 'pwg_token' => '1234abcd5678efgh',// get_pwg_token(), + ) + ); + +$template->append( + 'head_elements', + ''."\n" + ); + +if (isset($page['thumbnails'])) +{ + $template->assign( + array( + 'thumbnails' => $page['thumbnails'], + ) + ); + + // only display the batch link if we have more than 1 photo + if (count($page['thumbnails']) > 1) + { + $template->assign( + array( + 'batch_link' => $page['batch_link'], + 'batch_label' => sprintf( + l10n('Manage this set of %d photos'), + count($page['thumbnails']) + ), + ) + ); + } +} + +$query = ' +SELECT id,name,uppercats,global_rank + FROM '.CATEGORIES_TABLE.' +;'; + +display_select_cat_wrapper( + $query, + array(), + 'category_options' + ); + +// image level options +$tpl_options = array(); +foreach (array_reverse($conf['available_permission_levels']) as $level) +{ + $label = null; + + if (0 == $level) + { + $label = l10n('Everybody'); + } + else + { + $labels = array(); + $sub_levels = array_reverse($conf['available_permission_levels']); + foreach ($sub_levels as $sub_level) + { + if ($sub_level == 0 or $sub_level < $level) + { + break; + } + array_push( + $labels, + l10n( + sprintf( + 'Level %d', + $sub_level + ) + ) + ); + } + + $label = implode(', ', $labels); + } + $tpl_options[$level] = $label; +} +$selected_level = isset($_POST['level']) ? $_POST['level'] : 0; +$template->assign( + array( + 'level_options'=> $tpl_options, + 'level_options_selected' => array($selected_level) + ) + ); + +// +-----------------------------------------------------------------------+ +// | setup errors | +// +-----------------------------------------------------------------------+ + +$setup_errors = array(); + +$upload_base_dir = 'upload'; +$upload_dir = PHPWG_ROOT_PATH.$upload_base_dir; + +if (!is_dir($upload_dir)) +{ + if (!is_writable(PHPWG_ROOT_PATH)) + { + array_push( + $setup_errors, + sprintf( + l10n('Create the "%s" directory at the root of your Piwigo installation'), + $upload_base_dir + ) + ); + } +} +else +{ + if (!is_writable($upload_dir)) + { + @chmod($upload_dir, 0777); + + if (!is_writable($upload_dir)) + { + array_push( + $setup_errors, + sprintf( + l10n('Give write access (chmod 777) to "%s" directory at the root of your Piwigo installation'), + $upload_base_dir + ) + ); + } + } +} + +$template->assign( + array( + 'setup_errors'=> $setup_errors, + ) + ); + +// +-----------------------------------------------------------------------+ +// | sending html code | +// +-----------------------------------------------------------------------+ + +$template->assign_var_from_handle('ADMIN_CONTENT', 'plugin_admin_content'); +?> diff --git a/admin/photos_add_settings.php b/admin/photos_add_settings.php new file mode 100644 index 000000000..3deecb317 --- /dev/null +++ b/admin/photos_add_settings.php @@ -0,0 +1,155 @@ + $param) +{ + $param_name = 'upload_form_'.$param_shortname; + $form_values[$param_shortname] = $conf[$param_name]; +} + +// +-----------------------------------------------------------------------+ +// | process form | +// +-----------------------------------------------------------------------+ + +if (isset($_POST['submit'])) +{ + $updates = array(); + + // let's care about the specific checkbox that disable/enable other + // settings + $field = 'websize_resize'; + + if (empty($_POST[$field])) + { + $value = false; + } + else + { + $fields[] = 'websize_maxwidth'; + $fields[] = 'websize_maxheight'; + $fields[] = 'websize_quality'; + + $value = true; + } + + $updates[] = array( + 'param' => 'upload_form_'.$field, + 'value' => boolean_to_string($value), + ); + $form_values[$field] = $value;; + + // and now other fields, processed in a generic way + $fields[] = 'thumb_maxwidth'; + $fields[] = 'thumb_maxheight'; + $fields[] = 'thumb_quality'; + + foreach ($fields as $field) + { + $value = null; + if (!empty($_POST[$field])) + { + $value = $_POST[$field]; + } + $form_values[$field] = $value; + + if ($upload_form_config[$field]['can_be_null'] and empty($value)) + { + $updates[] = array( + 'param' => 'upload_form_'.$field, + 'value' => 'false' + ); + } + else + { + $min = $upload_form_config[$field]['min']; + $max = $upload_form_config[$field]['max']; + $pattern = $upload_form_config[$field]['pattern']; + + if (preg_match($pattern, $value) and $value >= $min and $value <= $max) + { + $updates[] = array( + 'param' => 'upload_form_'.$field, + 'value' => $value + ); + } + else + { + array_push( + $page['errors'], + sprintf( + l10n($upload_form_config[$field]['error_message']), + $min, + $max + ) + ); + } + } + } + + if (count($page['errors']) == 0) + { + mass_updates( + CONFIG_TABLE, + array( + 'primary' => array('param'), + 'update' => array('value') + ), + $updates + ); + + array_push( + $page['infos'], + l10n('Your configuration settings are saved') + ); + } +} + +// +-----------------------------------------------------------------------+ +// | template init | +// +-----------------------------------------------------------------------+ + +// specific case, "websize_resize" is a checkbox +$field = 'websize_resize'; +$form_values[$field] = $form_values[$field] ? 'checked="checked"' : ''; + +$template->assign( + array( + 'F_ADD_ACTION'=> PHOTOS_ADD_BASE_URL, + 'values' => $form_values + ) + ); + + +// +-----------------------------------------------------------------------+ +// | sending html code | +// +-----------------------------------------------------------------------+ + +$template->assign_var_from_handle('ADMIN_CONTENT', 'plugin_admin_content'); +?> \ No newline at end of file diff --git a/admin/template/goto/admin.tpl b/admin/template/goto/admin.tpl index 2376f10b5..c2242fbca 100644 --- a/admin/template/goto/admin.tpl +++ b/admin/template/goto/admin.tpl @@ -58,6 +58,7 @@ jQuery().ready(function(){ldelim}
{'Pictures'|@translate} 
    +
  • {'Add'|@translate}
  • {'Waiting'|@translate}
  • {'Thumbnails'|@translate}
  • {'Rating'|@translate}
  • diff --git a/admin/template/goto/default-layout.css b/admin/template/goto/default-layout.css index 9f4437d06..b972ab2ec 100644 --- a/admin/template/goto/default-layout.css +++ b/admin/template/goto/default-layout.css @@ -498,4 +498,53 @@ ul.holder li.bit-box-focus a.closebutton, ul.holder li.bit-box-focus a.closebutt .hidden { display:none;} #demo ul.holder li.bit-input input { padding: 2px 0 1px; border: 1px solid #999; } -.ie6fix {height:1px;width:1px; position:absolute;top:0px;left:0px;z-index:1;} \ No newline at end of file +.ie6fix {height:1px;width:1px; position:absolute;top:0px;left:0px;z-index:1;} + +/* Add photos, direct mode */ +#uploadBoxes P { + margin:0; + margin-bottom:2px; + padding:0; +} + +#batchLink { + text-align:center; +} + +.category_selection { + min-height:65px; + margin-top:5px; +} + +.category_selection TABLE { + margin:0; +} + +.formField { + width:650px; + margin:0 auto 20px auto; + padding:10px; + border: 2px solid #292929; +} + +.formFieldTitle { + font-weight:bold; + margin-bottom:10px; +} + +.formField P { + margin:0; +} + +.formField TH { + text-align:right; + padding-right: 5px; +} + +#uploadFormSettings input[type="text"] { + text-align:right; +} + +#uploadFormSettings TH { + width:50%; +} \ No newline at end of file diff --git a/admin/template/goto/photos_add_direct.tpl b/admin/template/goto/photos_add_direct.tpl new file mode 100644 index 000000000..419946734 --- /dev/null +++ b/admin/template/goto/photos_add_direct.tpl @@ -0,0 +1,185 @@ +{known_script id="jquery" src=$ROOT_URL|@cat:"template-common/lib/jquery.packed.js"} + +{literal} + +{/literal} + +{if $upload_mode eq 'html'} +{literal} + +{/literal} + +{elseif $upload_mode eq 'multiple'} + + + + +{/if} + +
    +

    {'Upload photos'|@translate}

    +
    + +{if count($setup_errors) > 0} +
    +
      + {foreach from=$setup_errors item=error} +
    • {$error}
    • + {/foreach} +
    +
    +{else} + +{if !empty($thumbnails)} +
    + {'Uploaded Photos'|@translate} +
    + {foreach from=$thumbnails item=thumbnail} + + {$thumbnail.file} + + {/foreach} +
    + +
    +{/if} + + +
    +{if $upload_mode eq 'multiple'} + +{/if} + +
    +
    {'Drop into category'|@translate}
    + + + + + + +
    + + + + + + + + + +
    {'Parent category'|@translate} + +
    {'Category name'|@translate} + +
    +
    +
    + +
    +
    {'Who can see these photos?'|@translate}
    + + +
    + +
    +
    {'Select files'|@translate}
    + +{if $upload_mode eq 'html'} +

    {'... or switch to the multiple files form'|@translate}

    + +

    {'JPEG files or ZIP archives with JPEG files inside please.'|@translate}

    + +
    + + +
    + +

    + +

    +{elseif $upload_mode eq 'multiple'} + + +

    + +

    + +

    {'... or switch to the old style form'|@translate}

    + +
    + + +

    + + +

    +{/if} +
    +{/if} diff --git a/admin/template/goto/photos_add_settings.tpl b/admin/template/goto/photos_add_settings.tpl new file mode 100644 index 000000000..10e4633dd --- /dev/null +++ b/admin/template/goto/photos_add_settings.tpl @@ -0,0 +1,74 @@ +{literal} + +{/literal} + +
    +

    {'Upload Photos'|@translate}

    +
    + +
    + +
    +
    {'Web size photo'|@translate}
    + + + + + + + + + + + + + + + + + + +
    {'Maximum Width'|@translate} {'pixels'|@translate}
    {'Maximum Height'|@translate} {'pixels'|@translate}
    {'Image Quality'|@translate} %
    +
    + +
    +
    {'Thumbnail'|@translate}
    + + + + + + + + + + + + + + +
    {'Maximum Width'|@translate} {'pixels'|@translate}
    {'Maximum Height'|@translate} {'pixels'|@translate}
    {'Image Quality'|@translate} %
    +
    + +

    + +

    + +
    -- cgit v1.2.3