You are here

function PclZip::privMerge in Quiz 6.6

Same name and namespace in other branches
  1. 6.5 includes/moodle/lib/pclzip/pclzip.lib.php \PclZip::privMerge()
1 call to PclZip::privMerge()
PclZip::merge in includes/moodle/lib/pclzip/pclzip.lib.php

File

includes/moodle/lib/pclzip/pclzip.lib.php, line 4999

Class

PclZip

Code

function privMerge(&$p_archive_to_add) {

  //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privMerge", "archive='".$p_archive_to_add->zipname."'");
  $v_result = 1;

  // ----- Look if the archive_to_add exists
  if (!is_file($p_archive_to_add->zipname)) {

    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive to add does not exist. End of merge.");

    // ----- Nothing to merge, so merge is a success
    $v_result = 1;

    // ----- Return

    //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
    return $v_result;
  }

  // ----- Look if the archive exists
  if (!is_file($this->zipname)) {

    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, duplicate the archive_to_add.");

    // ----- Do a duplicate
    $v_result = $this
      ->privDuplicate($p_archive_to_add->zipname);

    // ----- Return

    //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
    return $v_result;
  }

  // ----- Open the zip file

  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  if (($v_result = $this
    ->privOpenFd('rb')) != 1) {

    // ----- Return

    //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
    return $v_result;
  }

  // ----- Read the central directory informations
  $v_central_dir = array();
  if (($v_result = $this
    ->privReadEndCentralDir($v_central_dir)) != 1) {
    $this
      ->privCloseFd();

    //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
    return $v_result;
  }

  // ----- Go to beginning of File

  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in zip : ".ftell($this->zip_fd)."'");
  @rewind($this->zip_fd);

  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in zip : ".ftell($this->zip_fd)."'");

  // ----- Open the archive_to_add file

  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open archive_to_add in binary read mode");
  if (($v_result = $p_archive_to_add
    ->privOpenFd('rb')) != 1) {
    $this
      ->privCloseFd();

    // ----- Return

    //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
    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();

    //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
    return $v_result;
  }

  // ----- Go to beginning of File

  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in archive_to_add : ".ftell($p_archive_to_add->zip_fd)."'");
  @rewind($p_archive_to_add->zip_fd);

  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in archive_to_add : ".ftell($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

  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read 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

    //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
    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;

    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
    $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;

    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
    $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);

  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset");

  // ----- 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;

    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
    $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;

    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
    $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

    //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $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;

  // ----- 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

  //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  return $v_result;
}