civicrm / org.civicrm.civicase

CiviCase Extension
Other
9 stars 35 forks source link

C51-41: Add download all activity files page link #117

Closed reneolivo closed 6 years ago

reneolivo commented 6 years ago

This PR adds a page link that allows downloading all the files associated with an Activity in a single zip file.

How it works

pr-after

Technical details

A new page was added that retrieves the files for an activity and groups them in a single zip file that can be downloaded by the users.

The structure of the class is divided into the following units:

Validating that the activity id was provided

 private static function validateActivityId($activityId) {
    if (empty($activityId)) {
      http_response_code(404);
      CRM_Utils_System::civiExit();
    }
  }

Get the destination path for the zip file

  private static function getDestinationPath() {
    $config = CRM_Core_Config::singleton();

    return $config->customFileUploadDir;
  }

Getting the files associated to the activity

  private static function getActivityFilePaths($activityId) {
    $filePaths = [];
    $activityFiles = CRM_Core_BAO_File::getEntityFile('civicrm_activity', $activityId);

    foreach ($activityFiles as $activityFile) {
      $filePaths[] = $activityFile['fullPath'];
    }

    return $filePaths;
  }

Creating the zip file

  private static function createOrUpdateZipFile($zipFullPath, $filePaths) {
    $zipName = basename($zipFullPath);
    $zip = new ZipArchive();
    $mode = ZipArchive::CREATE | ZipArchive::OVERWRITE;
    $zip->open($zipFullPath, $mode);

    foreach ($filePaths as $filePath) {
      $zip->addFile($filePath, substr($filePath, strrpos($filePath, '/') + 1));
    }

    $zip->close();
  }

Downloading the newly created zip file

  private static function downloadZipFile($zipFullPath) {
    $zipName = basename($zipFullPath);

    header('Content-Type: application/zip');
    header('Content-disposition: attachment; filename=' . $zipName);
    header('Content-Length: ' . filesize($zipFullPath));

    readfile($zipFullPath);

    CRM_Utils_System::civiExit();
  }

Zip link

The final orchestration to download the zip file is this:

  public static function downloadAll() {
    $activityId = CRM_Utils_Array::value('activity_id', $_GET);

    self::validateActivityId($activityId);

    $zipName = 'activity-' . $activityId . '-files.zip';
    $zipDestination = self::getDestinationPath();
    $zipFullPath = $zipDestination . '/' . $zipName;
    $files = self::getActivityFilePaths($activityId);

    self::createOrUpdateZipFile($zipFullPath, $files);
    self::downloadZipFile($zipFullPath);
  }
reneolivo commented 6 years ago

Closing because the wrong target was selected by mistake.