$collection_download_max_size) { $totalsizeerror = true; $onload_message = array("title" => $lang["error"], "text" => $lang["collection_download_too_large"]); } } $show_download_format_selector = true; // Determine if the download format selector should be shown if ($collection_download_tar_size === 0 || $config_windows) { $show_download_format_selector = false; } // Determine if TAR should be the default option if ($show_download_format_selector && ($collection_download_tar_option || ($totalsize >= $collection_download_tar_size * 1024 * 1024))) { $tar_as_default = true; } else { $tar_as_default = false; } // Determine selected download format selector value if submitted if ($submitted && $show_download_format_selector) { $tar_selected = ($tardownload == 'on'); } else { $tar_selected = $tar_as_default; } $settings_id = (isset($collection_download_settings) && count($collection_download_settings) > 1) ? getval("settings", "") : 0; $usage = getval('usage', '-1', true); $usagecomment = getval('usagecomment', ''); // set the time limit to unlimited, default 300 is not sufficient here. set_time_limit(0); $archiver_fullpath = get_utility_path("archiver"); if (!$collection_download) { exit(escape($lang["download-of-collections-not-enabled"])); } elseif (!$use_zip_extension) { if (!$archiver_fullpath) { exit(escape($lang["archiver-utility-not-found"])); } if (!isset($collection_download_settings)) { exit(escape($lang["collection_download_settings-not-defined"])); } elseif (!is_array($collection_download_settings)) { exit(escape($lang["collection_download_settings-not-an-array"])); } if (!isset($archiver_listfile_argument)) { exit(escape($lang["listfile-argument-not-defined"])); } } // Should the configured archiver be used $archiver = ( $collection_download && $archiver_fullpath != false && (isset($archiver_listfile_argument)) && (isset($collection_download_settings) ) ? is_array($collection_download_settings) : false ); // This array will store all the available downloads. $available_sizes = array(); $count_data_only_types = 0; // Build the available sizes array for ($n = 0; $n < count($result); $n++) { $ref = $result[$n]["ref"]; // Load access level (0,1,2) for this resource $access = get_resource_access($result[$n]); // Get all possible sizes for this resource. If largest available has been requested then include internal or user could end up with no file depite being able to see the preview $sizes = get_all_image_sizes($size == "largest", $access >= 1); // Check availability of original file $p = get_resource_path($ref, true, "", false, $result[$n]["file_extension"]); if (file_exists($p) && (($access == 0) || ($access == 1 && $restricted_full_download)) && resource_download_allowed($ref, '', $result[$n]['resource_type'], -1, true)) { $available_sizes['original'][] = $ref; } // Check availability of each size and load it to the available_sizes array foreach ($sizes as $sizeinfo) { if (in_array($result[$n]['file_extension'], $ffmpeg_supported_extensions)) { $size_id = $sizeinfo['id']; // Video files will only have a 'pre' sized derivative so add to the sizes array $p = get_resource_path($ref, true, 'pre', false, $result[$n]['file_extension']); $size_id = 'pre'; if ( resource_download_allowed($ref, $size_id, $result[$n]['resource_type'], -1, true) && (hook('size_is_available', '', array($result[$n], $p, $size_id)) || file_exists($p)) ) { $available_sizes[$sizeinfo['id']][] = $ref; } } elseif (in_array($result[$n]['file_extension'], array_merge($ffmpeg_audio_extensions, ['mp3']))) { // Audio files are ported to mp3 and do not have different preview sizes $p = get_resource_path($ref, true, '', false, 'mp3'); if ( resource_download_allowed($ref, '', $result[$n]['resource_type'], -1, true) && (hook('size_is_available', '', array($result[$n], $p, '')) || file_exists($p)) ) { $available_sizes[$sizeinfo['id']][] = $ref; } } else { $size_id = $sizeinfo['id']; $size_extension = get_extension($result[$n], $size_id); $p = get_resource_path($ref, true, $size_id, false, $size_extension); if ( resource_download_allowed($ref, $size_id, $result[$n]['resource_type'], -1, true) && (hook('size_is_available', '', array($result[$n], $p, $size_id)) || file_exists($p)) ) { $available_sizes[$size_id][] = $ref; } } } if (in_array($result[$n]['resource_type'], $data_only_resource_types)) { $count_data_only_types++; } } if (isset($user_dl_limit) && intval($user_dl_limit) > 0) { $download_limit_check = get_user_downloads($userref, $user_dl_days); if ($download_limit_check + count($result) > $user_dl_limit) { $dlsummary = $download_limit_check . "/" . $user_dl_limit; $errormessage = $lang["download_limit_collection_error"] . " " . str_replace(array("[downloaded]","[limit]"), array($download_limit_check,$user_dl_limit), $lang['download_limit_summary']); if (getval("ajax", "") != "") { error_alert(escape($errormessage), true, 200); } else { include "../include/header.php"; $onload_message = array("title" => $lang["error"],"text" => $errormessage); include "../include/footer.php"; } exit(); } } if (count($available_sizes) === 0 && $count_data_only_types === 0) { error_alert($lang["nodownloadcollection"], false); exit(); } $used_resources = array(); $subbed_original_resources = array(); if ($submitted & !$totalsizeerror) { if ($exiftool_write && !$force_exiftool_write_metadata && !$tar_selected) { $exiftool_write_option = getval('write_metadata_on_download', '') == "yes"; } $id = uniqid("Col" . $collection); $collection_download_data = [ 'archiver' => $archiver, 'collection' => $collection, 'collectiondata' => $collectiondata, 'collection_resources' => $result, 'size' => $size, 'exiftool_write_option' => $exiftool_write_option, 'useoriginal' => $useoriginal, 'id' => $id, 'includetext' => $includetext, 'text' => $text ?? "", 'count_data_only_types' => $count_data_only_types, 'usage' => $usage, 'usagecomment' => str_replace(array('\r','\n'), " ", $usagecomment), 'settings_id' => $settings_id, 'include_csv_file' => $include_csv_file, 'include_alternatives' => $include_alternatives, 'collection_download_tar' => $tar_selected, 'k' => $k, ]; if ($offline_job_queue) { // Only need to store resource IDS, not full search data $collection_download_data["result"] = array_column($result, "ref", "ref"); // tar files are not an option with offline jobs $collection_download_data['collection_download_tar'] = false; $modified_job_data = hook("collection_download_modify_job", "", [$collection_download_data]); if (is_array($modified_job_data)) { $collection_download_data = $modified_job_data; } job_queue_add( 'collection_download', $collection_download_data, '', '', $lang["oj-collection-download-success-text"], $lang["oj-collection-download-failure-text"], '', JOB_PRIORITY_USER ); $job_created = true; $onload_message = [ "title" => $lang['collection_download'], "text" => $lang['jq_notify_user_preparing_archive'], ]; } else { $zipinfo = process_collection_download($collection_download_data); if (empty($zipinfo)) { error_alert(escape($lang["download_limit_collection_error"]), true, 200); } if ($zipinfo["completed"] ?? false) { // A tar file was requested and sent. Nothing further to do. collection_log($collection, LOG_CODE_COLLECTION_COLLECTION_DOWNLOADED, "", "tar - " . $size); exit(); } else { // Get the file size of the archive. $filesize = filesize_unlimited($zipinfo["path"]); header("Content-Disposition: attachment; filename=" . $zipinfo["filename"]); if ($archiver) { header("Content-Type: " . $collection_download_settings[$settings_id]["mime"]); } else { header("Content-Type: application/zip"); } if ($use_zip_extension) { header("Content-Transfer-Encoding: binary"); } header("Content-Length: " . $filesize); ignore_user_abort(true); // collection download has a problem with leaving junk files when this script is aborted client side. This seems to fix that by letting the process run its course. set_time_limit(0); $sent = 0; $handle = fopen($zipinfo["path"], "r"); // Now loop through the file and echo out chunks of file data while ($sent < $filesize) { echo fread($handle, $download_chunk_size); $sent += $download_chunk_size; } // File send complete, log to daily stat daily_stat('Downloaded KB', 0, floor($sent / 1024)); // Remove archive. if ($use_zip_extension || $archiver) { $GLOBALS["use_error_exception"] = true; try { $usertempdir = get_temp_dir(false, "rs_" . $GLOBALS["userref"] . "_" . $id); rmdir($usertempdir); } catch (Exception $e) { debug("collection_download: Attempt delete temp folder failed. Reason: {$e->getMessage()}"); } unset($GLOBALS["use_error_exception"]); } collection_log($collection, LOG_CODE_COLLECTION_COLLECTION_DOWNLOADED, "", $size); hook('beforedownloadcollectionexit'); exit(); } } } include "../include/header.php"; ?>