You are here

function zoomapi_api_download_recording in Zoom API 7.2

Download Recording.

Downloads a zoom recording to the specified destination / filename.

1 call to zoomapi_api_download_recording()
zoomapi_download_recording in ./zoomapi.module
Download Recording.

File

./zoomapi.api.inc, line 292
API callbacks for Zoom API module.

Code

function zoomapi_api_download_recording($zoom_meeting_recording, $destination_directory, $filename = '', $context = []) {
  try {

    // Check that the destination is writable.
    $temporary_directory = 'temporary://';
    if (!file_prepare_directory($temporary_directory, FILE_MODIFY_PERMISSIONS)) {
      $msg = t('The directory %dir is not writable, because it does not have the correct permissions set.', [
        '%dir' => drupal_realpath($temporary_directory),
      ]);
      throw new Exception($msg);
    }
    $file_type = strtolower($zoom_meeting_recording['file_type']);
    $filename = $filename ?: $zoom_meeting_recording['id'] . '_' . strtotime($zoom_meeting_recording['recording_start']) . '.' . $file_type;
    if (empty($context['recording'])) {
      $context['recording'] = $zoom_meeting_recording;
    }
    drupal_alter('zoomapi_recording_filename', $filename, $context);
    if (strtolower(substr($filename, -1 * strlen($file_type))) != $file_type) {
      $filename .= ".{$file_type}";
    }
    $zoom_client = zoomapi_client();
    $url = url($zoom_meeting_recording['download_url'], [
      'query' => [
        'access_token' => $zoom_client
          ->generateJwt(),
      ],
    ]);

    // Check that the destination is writable.
    $mode = variable_get('file_chmod_directory', 0775);

    // This first chmod check is for other systems such as S3, which don't work
    // with file_prepare_directory().
    if (!drupal_chmod($destination_directory, $mode) && !file_prepare_directory($destination_directory, FILE_CREATE_DIRECTORY)) {
      $msg = t('File %file could not be copied, because the destination directory %destination is not configured correctly.', [
        '%file' => $url,
        '%destination' => drupal_realpath($destination_directory),
      ]);
      throw new Exception($msg);
    }

    // Check the headers to make sure it exists and is within the allowed size.
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, TRUE);
    curl_setopt($ch, CURLOPT_NOBODY, TRUE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

    // Causes a warning if PHP safe mode is on.
    @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);

    // Set a user agent - some hosts block requests unless header is present.
    $curl_version = curl_version();
    curl_setopt($ch, CURLOPT_USERAGENT, 'PHP-curl/' . $curl_version['version']);
    curl_exec($ch);
    $info = curl_getinfo($ch);
    if ($info['http_code'] != 200) {
      curl_setopt($ch, CURLOPT_HTTPGET, TRUE);
      $file_contents = curl_exec($ch);
      $info = curl_getinfo($ch);
    }
    curl_close($ch);
    if ($info['http_code'] != 200) {
      $replacements = [
        '@filename' => $filename,
        '@code' => $info['http_code'],
      ];
      switch ($info['http_code']) {
        case 403:
          $replacements['reason'] = 'Access to the file was denied.';
          break;
        case 404:
          $replacements['reason'] = 'Not found.';
          break;
      }
      $msg = t('The recording @filename for meeting @meeting_id could not be downloaded. HTTP error (@code). Reason !reason', $replacements);
      throw new Exception($msg);
    }

    // Update the $url variable to reflect any redirects.
    $url = $info['url'];
    $filename = zoomapi_clean_filename($filename);
    $filepath = file_create_filename($filename, $temporary_directory);

    // Set progress bar information.
    $options = [
      'key' => $url,
      'filepath' => $filepath,
    ];
    zoomapi_set_transfer_options($options);
    $transfer_success = FALSE;

    // If we've already downloaded the entire file because the header-retrieval
    // failed, just use the contents we have.
    if (isset($file_contents)) {
      if ($fp = @fopen($filepath, 'w')) {
        fwrite($fp, $file_contents);
        fclose($fp);
        $transfer_success = TRUE;
      }
    }
    else {
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, $url);
      curl_setopt($ch, CURLOPT_HEADER, FALSE);
      curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'zoomapi_download_recording_curl_write');

      // Causes a warning if PHP safe mode is on.
      @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);

      // Set a user agent - some hosts block requests unless header is present.
      $curl_version = curl_version();
      curl_setopt($ch, CURLOPT_USERAGENT, 'PHP-curl/' . $curl_version['version']);
      $transfer_success = curl_exec($ch);
      curl_close($ch);
    }
    if ($transfer_success) {
      $download_size = filesize($filepath);
      if ($download_size != $zoom_meeting_recording['file_size']) {
        $msg = t('The file size (@new_size) for recording @recording_id of meeting @meeting_id did not match the specified file size (@orig_size).', [
          '@new_size' => $download_size,
          '@recording_id' => $zoom_meeting_recording['id'],
          '@meeting_id' => $zoom_meeting_recording['meeting_id'],
          '@orig_size' => $zoom_meeting_recording['file_size'],
        ]);
        $transfer_success = FALSE;
        throw new Exception($msg);
      }
      $file = zoomapi_save_file($filepath, $destination_directory);
      return (array) $file;
    }
  } catch (\Exception $e) {
    watchdog(__FUNCTION__, 'Unable to download Zoom recording @filename. Error: @e', [
      '@e' => $e
        ->getMessage(),
      '@filename' => $filename,
    ], WATCHDOG_CRITICAL);
    return FALSE;
  } finally {

    // Delete the temporary file.
    if (isset($file) && isset($filepath) && $filepath !== $file->uri) {
      @unlink($filepath);
    }
  }
}