How can I zip uploaded files?

If the form includes large files or several files that you want to keep together it may help to add them to a 'zip' archive. This FAQ has code that will let you do that and then save and / or email the zipped file.

This code requires the PHP Zip extension to be installed. This is usually included with PHP 5.3 but may not be present with earlier versions. Check Site | System Information | PHP Information to see if Zip is installed. 

In your form On Submit event add a Custom Code action after the Upload Files action and before any Email action where you want to attach the zipped file. Add this code to the Custom Code action:

<?php
// you can set a name for the zip file here if you need to.
// the name should be URL safe with no spaces or special characters.
$zip_file_name = '';

// check if there are any files to zip
if ( count($form->files) < 1 ) {
  return;
}
jimport('joomla.filesystem.file');
$files = array();
// loop through the files and unpack any arrays from the widget
foreach ( $form->files as $k => $f ) {
  if ( is_array($f) && !isset($f['name']) ) {
    foreach ($f as $kk => $ff ) {
      $files[$k.'_'.$kk] = $ff;
    }
  } else {
    $files[$k] = $f;
  }
}

$first_file = true;
foreach ( $files as $k => $f ) {
  if ( !JFile::exists($f['path']) ) {
    // check if the file exists
    continue;
  }
  if ( $first_file ) {
    // if it's the first file create the archive
        // if it's the first file create the archive
    if ( $zip_file_name ) {
      $zip_path = str_replace($f['name'], $zip_file_name.'.zip', $f['path']);
    } else {
      $zip_path = JFile::stripExt($f['path']).'.zip';
    }
    $zip = new ZipArchive;
    $result = $zip->open($zip_path, ZipArchive::OVERWRITE);
    if ( $result !== true ) {
      // unable to open ZipArchive
      return;
    }
    // create a new $form->files entry
    $form->files['upload_zip'] = array(
      'name' => 'docs',
      'original_name' => '',
      'path' => $zip_path,
      'size' => '',
      'link' => str_replace(JPATH_SITE.DS, JURI::root(), $zip_path)
    );
    $first_file = false;
  }
  // add the file to the archive
  $zip->addFile($f['path'], $f['name']);
  // uncomment the next line to delete the original file
//JFile::delete($f['path']);
}
$zip->close();
// update the size now the archive is complete
$form->files['upload_zip']['size'] = filesize($zip_path);
?>

This code should work with one or more standard file upload elements and with the File Upload Widget. It will zip all of the uploaded files; you will need to edit it if you wish to exclude some of them.
By default the new zip file will be named after the first uploaded file found; edit the highlighted code to change this.
There is a line near the end that you can uncomment if you want to delete the original files after they have been added to the zip file.
To attach the zipped file to an email, add upload_zip to the Email action Attachments box.

The code here has been updated to let you specify a name for the zip file in the line near the beginning. The name should be a text string but can be built from $form->data entries using PHP.

Category: CFv4 File uploads

Comments:

You need to login to be able to post a comment.