function tripal_file_upload_merge

3.x tripal.upload.inc tripal_file_upload_merge($filename, $type, $user_dir)

Merges all chunks into a single file

1 call to tripal_file_upload_merge()

File

tripal/includes/tripal.upload.inc, line 92

Code

function tripal_file_upload_merge($filename, $type, $user_dir) {
  global $user;

  $module = $_GET['module'];

  $status = 'merging';
  $message = '';

  // Build the paths to the temp directory and merged file.
  $temp_dir = $user_dir . '/temp' . '/' . $filename;
  $merge_file = $user_dir . '/' . $filename;

  // If the temp directory where the chunks are found does not exist and the
  // client is requesting merge then most likely the file has already been
  // merged and the user hit the upload button again.
  if (file_exists($temp_dir)) {
    // Get the upload log.
    $log = tripal_file_upload_read_log($temp_dir);

    // Keep up with the expected file size.
    $merge_size = 0;

    // Open the new merged file.
    $merge_fh = fopen($merge_file, "w");
    if ($merge_fh) {
      if (flock($merge_fh, LOCK_EX)) {
        $chunks_written = $log['chunks_written'];
        $max_chunk = max(array_keys($chunks_written));
        // Iterate through the chunks in order and see if any are missing.
        // If so then break out of the loop and fail. Otherwise concatentate
        // them together.
        for ($i = 0; $i <= $max_chunk; $i++) {
          if (!array_key_exists($i, $chunks_written)) {
            $status = 'failed';
            $message = 'Missing some chunks. Cannot complete file merge.';
            break;
          }
          $merge_size += $chunks_written[$i];
          $chunk_file = $temp_dir . '/' . $filename . '.chunk.' . $i;
          $cfh = fopen($chunk_file, 'r');
          while ($data = fread($cfh, 1024)) {
            fwrite($merge_fh, $data);
          }
          fclose($cfh);
        } // end for ($i = 0; $i <= $max_chunk; $i++) { ...

        if (filesize($merge_file) != $merge_size) {
          $status = 'failed';
          $message = 'File was uploaded but final merged size is incorrect: ' . $merge_file . '.';
        }
      }
      else {
        $status = 'failed';
        $message = 'Cannot lock merged file for writing: ' . $merge_file . '.';
      }
    }
    else {
      $status = 'failed';
      $message = 'Cannot open merged file: ' . $merge_file . '.';
    }
    flock($merge_fh, LOCK_UN);
    fclose($merge_fh);
  }

  // Make sure the merged file exists
  if (!file_exists($merge_file)) {
    $status = 'failed';
    $message = 'Merge file is missing after upload ' . $merge_file . '.';
  }

  $file_id = NULL;

  // If the file has been successfully merged then do a few other things...
  if ($status != 'failed') {

    // See if this file is already managed if so, then it has been uploaded
    // before and we don't need to add a managed item again.
    $fid = db_select('file_managed', 'fm')
      ->fields('fm', ['fid'])
      ->condition('uri', $merge_file)
      ->execute()
      ->fetchField();

    // Add the file if it is not already managed.
    if (!$fid) {
      $file = new stdClass();
      $file->uri = $merge_file;
      $file->filename = $filename;
      $file->filemime = file_get_mimetype($merge_file);
      $file->uid = $user->uid;
      $file->status = FILE_STATUS_PERMANENT;
      $file = file_save($file);
      $fid = $file->fid;
    }

    // Reload the file object to get a full object.
    $file_id = $fid;
    $file = file_load($fid);

    // Set the file as being managed by Tripal.
    file_usage_add($file, 'tripal', $type, 0);

    // Set the file expiration.
    tripal_reset_file_expiration($fid);

    // Generate an md5 file the uploaded file.
    $full_path = drupal_realpath($file->uri);
    $md5sum = md5_file($full_path);
    $md5sum_file = fopen("$full_path.md5", "w");
    fwrite($md5sum_file, $md5sum);
    fclose($md5sum_file);

    // Remove the temporary directory.
    file_unmanaged_delete_recursive($temp_dir);

    // Now let the submitting module deal with it.
    $function = $module . '_handle_uploaded_file';
    if (function_exists($function)) {
      $function($file, $type);
    }
    $status = 'completed';
  }

  if ($status == 'failed') {
    watchdog('tripal', $message, array(), WATCHDOG_ERROR);
  }
  drupal_json_output(array(
    'status' => $status,
    'message' => $message,
    'file_id' => $file_id,
  ));
}