'string', 'multipart_download_type' => 'string', 'track_progress' => 'bool', 'target_part_size_bytes' => 'int', ]; /** @var string|array|null */ private string|array|null $source; /** @var array */ private array $downloadRequestArgs; /** @var AbstractDownloadHandler|null */ private ?AbstractDownloadHandler $downloadHandler; /** * @param string|array|null $source The object to be downloaded from S3. * It can be either a string with a S3 URI or an array with a Bucket and Key * properties set. * @param array $downloadRequestArgs * @param array $config The configuration to be used for this operation: * - multipart_download_type: (string, optional) * Overrides the resolved value from the transfer manager config. * - response_checksum_validation: (string, optional) Overrides the resolved * value from transfer manager config for whether checksum validation * should be done. This option will be considered just if ChecksumMode * is not present in the request args. * - track_progress: (bool) Overrides the config option set in the transfer * manager instantiation to decide whether transfer progress should be * tracked. * - target_part_size_bytes: (int) The part size in bytes to be used * in a range multipart download. If this parameter is not provided * then it fallbacks to the transfer manager `target_part_size_bytes` * config value. * @param AbstractDownloadHandler|null $downloadHandler * @param AbstractTransferListener[]|null $listeners * @param AbstractTransferListener|null $progressTracker * @param S3ClientInterface|null $s3Client */ public function __construct( string|array|null $source, array $downloadRequestArgs = [], array $config = [], ?AbstractDownloadHandler $downloadHandler = null, array $listeners = [], ?AbstractTransferListener $progressTracker = null, ?S3ClientInterface $s3Client = null ) { parent::__construct($listeners, $progressTracker, $config, $s3Client); $this->source = $source; $this->downloadRequestArgs = $downloadRequestArgs; $this->config = $config; if ($downloadHandler === null) { $downloadHandler = new StreamDownloadHandler(); } $this->downloadHandler = $downloadHandler; } /** * @param DownloadRequest $downloadRequest * @param FileDownloadHandler $downloadHandler * * @return self */ public static function fromDownloadRequestAndDownloadHandler( DownloadRequest $downloadRequest, FileDownloadHandler $downloadHandler ): self { return new self( $downloadRequest->getSource(), $downloadRequest->getObjectRequestArgs(), $downloadRequest->getConfig(), $downloadHandler, $downloadRequest->getListeners(), $downloadRequest->getProgressTracker() ); } /** * @return array|string|null */ public function getSource(): array|string|null { return $this->source; } /** * @return array */ public function getObjectRequestArgs(): array { return $this->downloadRequestArgs; } /** * @return AbstractDownloadHandler */ public function getDownloadHandler(): AbstractDownloadHandler { return $this->downloadHandler; } /** * Helper method to normalize the source as an array with: * - Bucket * - Key * * @return array */ public function normalizeSourceAsArray(): array { // If source is null then fall back to getObjectRequest. $source = $this->getSource() ?? [ 'Bucket' => $this->downloadRequestArgs['Bucket'] ?? null, 'Key' => $this->downloadRequestArgs['Key'] ?? null, ]; if (is_string($source)) { $sourceAsArray = S3TransferManager::s3UriAsBucketAndKey($source); } elseif (is_array($source)) { $sourceAsArray = $source; } else { throw new S3TransferException( "Unsupported source type `" . gettype($source) . "`" ); } foreach (['Bucket', 'Key'] as $reqKey) { if (empty($sourceAsArray[$reqKey])) { throw new \InvalidArgumentException( "`$reqKey` is required but not provided in " . implode(', ', array_keys($sourceAsArray)) . "." ); } } return $sourceAsArray; } }