PclZip::privMerge PHP Метод

privMerge() публичный Метод

--------------------------------------------------------------------------------
public privMerge ( &$p_archive_to_add )
    public function privMerge(&$p_archive_to_add)
    {
        $v_result = 1;
        // ----- Look if the archive_to_add exists
        if (!is_file($p_archive_to_add->zipname)) {
            // ----- Nothing to merge, so merge is a success
            $v_result = 1;
            // ----- Return
            return $v_result;
        }
        // ----- Look if the archive exists
        if (!is_file($this->zipname)) {
            // ----- Do a duplicate
            $v_result = $this->privDuplicate($p_archive_to_add->zipname);
            // ----- Return
            return $v_result;
        }
        // ----- Open the zip file
        if (($v_result = $this->privOpenFd('rb')) != 1) {
            // ----- Return
            return $v_result;
        }
        // ----- 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);
        // ----- Open the archive_to_add file
        if (($v_result = $p_archive_to_add->privOpenFd('rb')) != 1) {
            $this->privCloseFd();
            // ----- Return
            return $v_result;
        }
        // ----- 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();
            return $v_result;
        }
        // ----- Go to beginning of File
        @rewind($p_archive_to_add->zip_fd);
        // ----- Creates a temporay file
        $v_zip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.tmp';
        // ----- 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();
            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \'' . $v_zip_temp_name . '\' in binary write mode');
            // ----- Return
            return PclZip::errorCode();
        }
        // ----- 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;
        }
        // ----- 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;
        }
        // ----- Store the offset of the central dir
        $v_offset = @ftell($v_zip_temp_fd);
        // ----- 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;
        }
        // ----- 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;
        }
        // ----- Merge the file comments
        $v_comment = $v_central_dir['comment'] . ' ' . $v_central_dir_to_add['comment'];
        // ----- Calculate the size of the (new) central header
        $v_size = @ftell($v_zip_temp_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 fd
        $v_swap = $this->zip_fd;
        $this->zip_fd = $v_zip_temp_fd;
        $v_zip_temp_fd = $v_swap;
        // ----- 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;
            // ----- Reset the file list
            unset($v_header_list);
            // ----- Return
            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;
        // ----- Close
        $this->privCloseFd();
        $p_archive_to_add->privCloseFd();
        // ----- Close the temporary file
        @fclose($v_zip_temp_fd);
        // ----- 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;
    }