You are here

function PclZip::privAddFile in Quiz 6.5

Same name and namespace in other branches
  1. 6.6 includes/moodle/lib/pclzip/pclzip.lib.php \PclZip::privAddFile()
1 call to PclZip::privAddFile()
PclZip::privAddFileList in includes/moodle/lib/pclzip/pclzip.lib.php

File

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

Class

PclZip

Code

function privAddFile($p_filedescr, &$p_header, &$p_options) {

  //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddFile", "filename='".$p_filedescr['filename']."'");
  $v_result = 1;

  // ----- Working variable
  $p_filename = $p_filedescr['filename'];

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

    // ----- Return

    //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
    return PclZip::errorCode();
  }

  // ----- Look for a stored different filename
  if (isset($p_filedescr['stored_filename'])) {
    $v_stored_filename = $p_filedescr['stored_filename'];

    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'Stored filename is NOT the same "'.$v_stored_filename.'"');
  }
  else {
    $v_stored_filename = $p_filedescr['stored_filename'];

    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'Stored filename is the same');
  }

  // ----- Set the file properties
  clearstatcache();
  $p_header['version'] = 20;
  $p_header['version_extracted'] = 10;
  $p_header['flag'] = 0;
  $p_header['compression'] = 0;
  $p_header['mtime'] = filemtime($p_filename);
  $p_header['crc'] = 0;
  $p_header['compressed_size'] = 0;
  $p_header['size'] = filesize($p_filename);
  $p_header['filename_len'] = strlen($p_filename);
  $p_header['extra_len'] = 0;
  $p_header['comment_len'] = 0;
  $p_header['disk'] = 0;
  $p_header['internal'] = 0;

  //    $p_header['external'] = (is_file($p_filename)?0xFE49FFE0:0x41FF0010);
  $p_header['external'] = is_file($p_filename) ? 0x0 : 0x10;

  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header external extension '".sprintf("0x%X",$p_header['external'])."'");
  $p_header['offset'] = 0;
  $p_header['filename'] = $p_filename;
  $p_header['stored_filename'] = $v_stored_filename;
  $p_header['extra'] = '';
  $p_header['comment'] = '';
  $p_header['status'] = 'ok';
  $p_header['index'] = -1;

  // ----- Look for pre-add callback
  if (isset($p_options[PCLZIP_CB_PRE_ADD])) {

    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_ADD]."()') is defined for the extraction");

    // ----- 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);');
    if ($v_result == 0) {

      // ----- Change the file status
      $p_header['status'] = "skipped";
      $v_result = 1;
    }

    // ----- 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']);

      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New stored filename is '".$p_header['stored_filename']."'");
    }
  }

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

  // ----- Look if no error, or file not skipped
  if ($p_header['status'] == 'ok') {

    // ----- Look for a file
    if (is_file($p_filename)) {

      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "'".$p_filename."' is a file");

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

        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
        return PclZip::errorCode();
      }
      if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {

        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will not be compressed");

        // ----- Read the file content
        $v_content_compressed = @fread($v_file, $p_header['size']);

        // ----- Calculate the CRC
        $p_header['crc'] = @crc32($v_content_compressed);

        // ----- Set header parameters
        $p_header['compressed_size'] = $p_header['size'];
        $p_header['compression'] = 0;
      }
      else {

        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will be compressed");

        // ----- Read the file content
        $v_content = @fread($v_file, $p_header['size']);

        // ----- Calculate the CRC
        $p_header['crc'] = @crc32($v_content);

        // ----- Compress the file
        $v_content_compressed = @gzdeflate($v_content);

        // ----- Set header parameters
        $p_header['compressed_size'] = strlen($v_content_compressed);
        $p_header['compression'] = 8;
      }

      // ----- Look for encryption

      /*
      if ((isset($p_options[PCLZIP_OPT_CRYPT]))
      		    && ($p_options[PCLZIP_OPT_CRYPT] != "")) {
        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File need to be crypted ....");

        // Should be a random header
        $v_header = 'xxxxxxxxxxxx';
      	      $v_content_compressed = PclZipUtilZipEncrypt($v_content_compressed,
      		                                           $p_header['compressed_size'],
      	                                               $v_header,
      												   $p_header['crc'],
      												   "test");
      												
        $p_header['compressed_size'] += 12;
        $p_header['flag'] = 1;

        // ----- Add the header to the data
        $v_content_compressed = $v_header.$v_content_compressed;
        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Size after header : ".strlen($v_content_compressed)."");
      }
      */

      // ----- Call the header generation
      if (($v_result = $this
        ->privWriteFileHeader($p_header)) != 1) {
        @fclose($v_file);

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

      // ----- Write the compressed (or not) content
      @fwrite($this->zip_fd, $v_content_compressed, $p_header['compressed_size']);

      // ----- Close the file
      @fclose($v_file);
    }
    else {

      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "'".$p_filename."' is a folder");

      // ----- Look for directory last '/'
      if (@substr($p_header['stored_filename'], -1) != '/') {
        $p_header['stored_filename'] .= '/';
      }

      // ----- Set the file properties
      $p_header['size'] = 0;

      //$p_header['external'] = 0x41FF0010;   // Value for a folder : to be checked
      $p_header['external'] = 0x10;

      // Value for a folder : to be checked
      // ----- Call the header generation
      if (($v_result = $this
        ->privWriteFileHeader($p_header)) != 1) {

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

  // ----- Look for post-add callback
  if (isset($p_options[PCLZIP_CB_POST_ADD])) {

    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_ADD]."()') is defined for the extraction");

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

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