From 7533921c348f772e58d093fe235010f49ff294cb Mon Sep 17 00:00:00 2001 From: Zachary Schneider Date: Thu, 8 Jul 2021 21:18:16 -0700 Subject: [PATCH] fix bugs --- docs/helpers.md | 3 -- src/Config.php | 17 +++++------ ...ndException.php => NoResultsException.php} | 2 +- src/Helpers/DownloadHelper.php | 12 ++++---- src/Helpers/FileOperationsHelper.php | 5 ---- src/Helpers/UploadHelper.php | 2 +- src/Http/Endpoint.php | 2 +- .../ApplyAuthorizationMiddleware.php | 2 +- src/Object/File.php | 30 +++++++++---------- src/Object/File/DownloadOptions.php | 4 +-- src/Object/File/ServerSideEncryption.php | 4 +-- src/Operations/BucketOperationsTrait.php | 10 +++---- src/Operations/DownloadOperationsTrait.php | 9 ++---- src/Operations/FileOperationsTrait.php | 29 +++++++----------- src/Operations/UploadOperationsTrait.php | 2 +- src/Response/FileList.php | 7 +++-- src/Utils.php | 2 ++ 17 files changed, 61 insertions(+), 81 deletions(-) rename src/Exceptions/{NotFoundException.php => NoResultsException.php} (66%) diff --git a/docs/helpers.md b/docs/helpers.md index 5649041..3685f85 100644 --- a/docs/helpers.md +++ b/docs/helpers.md @@ -51,9 +51,6 @@ $client->bucket(Bucket|'bucketId')->listAllFileVersions(); // Get information on a file. $client->file()->getInfo('fileId'); -// Get a file by ID. -$client->file()->getById('fileId'); - // Get a file by name. $client->file()->getByName('fileName'); diff --git a/src/Config.php b/src/Config.php index 709feed..c9c276d 100644 --- a/src/Config.php +++ b/src/Config.php @@ -45,7 +45,7 @@ class Config /** * Custom Guzzle handler or handler stack. - * @var callable|\GuzzleHttp\HandlerStack + * @var \GuzzleHttp\HandlerStack */ private $handler; @@ -161,14 +161,6 @@ public function middleware(): array public function handler(): HandlerStack { - if (!$this->handler) { - $this->handler = HandlerStack::create(); - } - - if (is_callable($this->handler) && !$this->handler instanceof HandlerStack) { - $this->handler = new HandlerStack(($this->handler)); - } - return $this->handler; } @@ -202,7 +194,12 @@ public static function fromArray($data): Config private function setOptions(array $options) { $options = array_merge(static::DEFAULTS, $options); - $this->handler = $options['handler']; + $this->handler = $options['handler'] ?? HandlerStack::create(); + + if (is_callable($this->handler) && !$this->handler instanceof HandlerStack) { + $this->handler = new HandlerStack(($this->handler)); + } + $this->maxRetries = $options['maxRetries']; $this->maxFileCount = $options['maxFileCount']; $this->maxKeyCount = $options['maxKeyCount']; diff --git a/src/Exceptions/NotFoundException.php b/src/Exceptions/NoResultsException.php similarity index 66% rename from src/Exceptions/NotFoundException.php rename to src/Exceptions/NoResultsException.php index 5c434cc..41ce9bc 100644 --- a/src/Exceptions/NotFoundException.php +++ b/src/Exceptions/NoResultsException.php @@ -3,6 +3,6 @@ namespace Zaxbux\BackblazeB2\Exceptions; /** @package BackblazeB2\Exceptions */ -class NotFoundException extends \Exception { +class NoResultsException extends \Exception { } diff --git a/src/Helpers/DownloadHelper.php b/src/Helpers/DownloadHelper.php index 5381f00..1e91f14 100644 --- a/src/Helpers/DownloadHelper.php +++ b/src/Helpers/DownloadHelper.php @@ -30,11 +30,13 @@ public function download( $options = DownloadOptions::fromArray($options ?? []); } - // Build query string from query parameters and download options. - $queryString = implode('&', [http_build_query($query ?? []), $options->toQueryString() ?? []]); - - $response = $this->getHttpClient()->request($headersOnly ? 'HEAD' : 'GET', $downloadUrl, [ - 'query' => $queryString, + $response = $this->getHttpClient()->request( + $headersOnly ? 'HEAD' : 'GET', + Utils::joinPaths( + $this->client->accountAuthorization()->downloadUrl(), + $downloadUrl + ), [ + 'query' => Utils::filterRequestOptions([], $query, $options->getDownloadQueryOptions()), 'headers' => $options->getHeaders(), 'sink' => $sink ?? null, 'stream' => Utils::isStream($sink), diff --git a/src/Helpers/FileOperationsHelper.php b/src/Helpers/FileOperationsHelper.php index 9f7f6a7..6b3ba65 100644 --- a/src/Helpers/FileOperationsHelper.php +++ b/src/Helpers/FileOperationsHelper.php @@ -121,11 +121,6 @@ public function getInfo(string $fileId): File return $this->client->getFileInfo($fileId); } - public function getById(string $fileId): File - { - return $this->client->getFileById($fileId); - } - public function getByName(string $fileName): File { return $this->client->getFileByName($fileName); diff --git a/src/Helpers/UploadHelper.php b/src/Helpers/UploadHelper.php index 320d817..24df083 100644 --- a/src/Helpers/UploadHelper.php +++ b/src/Helpers/UploadHelper.php @@ -76,8 +76,8 @@ public function uploadStream( // Upload as regular file return $this->client->uploadFile( - $bucketId, $fileName, + $bucketId, $stream, $contentType, $fileInfo, diff --git a/src/Http/Endpoint.php b/src/Http/Endpoint.php index abb6e52..2db9840 100644 --- a/src/Http/Endpoint.php +++ b/src/Http/Endpoint.php @@ -15,7 +15,7 @@ final class Endpoint public const DELETE_FILE_VERSION = 'b2_delete_file_version'; public const DELETE_KEY = 'b2_delete_key'; public const DOWNLOAD_FILE_BY_ID = 'b2_download_file_by_id'; - public const DOWNLOAD_FILE_BY_NAME = 'b2_download_file_by_name'; + public const DOWNLOAD_FILE_BY_NAME = 'file'; public const FINISH_LARGE_FILE = 'b2_finish_large_file'; public const GET_DOWNLOAD_AUTHORIZATION = 'b2_get_download_authorization'; public const GET_FILE_INFO = 'b2_get_file_info'; diff --git a/src/Http/Middleware/ApplyAuthorizationMiddleware.php b/src/Http/Middleware/ApplyAuthorizationMiddleware.php index eb0b556..1d2457a 100644 --- a/src/Http/Middleware/ApplyAuthorizationMiddleware.php +++ b/src/Http/Middleware/ApplyAuthorizationMiddleware.php @@ -46,7 +46,7 @@ public function __invoke(callable $next): callable protected function applyToken(RequestInterface $request): RequestInterface { $request = Psr7Utils::modifyRequest($request, [ - 'uri' => new Uri(Utils::joinPaths($this->client->accountAuthorization()->apiUrl(), (string)$request->getUri())), + 'uri' => new Uri(Utils::joinPaths($request->getUri()->getHost() ? '' : $this->client->accountAuthorization()->apiUrl(), (string)$request->getUri())), 'set_headers' => [ 'Authorization' => $this->client->accountAuthorization()->authorizationToken(), ], diff --git a/src/Object/File.php b/src/Object/File.php index 42ee8ea..2efe0eb 100644 --- a/src/Object/File.php +++ b/src/Object/File.php @@ -144,7 +144,7 @@ class File implements B2ObjectInterface * @param int $partNumber */ public function __construct( - string $id, + ?string $id = null, ?string $name = null, ?string $bucketId = null, ?string $action = null, @@ -183,7 +183,7 @@ public function __construct( /** * Get the file account ID. */ - public function accountId(): string + public function accountId(): ?string { return $this->accountId; } @@ -203,7 +203,7 @@ public function setAccountId(string $accountId): File /** * Get the file ID. */ - public function id(): string + public function id(): ?string { return $this->id; } @@ -223,7 +223,7 @@ public function setId(string $id): File /** * Get the file name (path). */ - public function name(): string + public function name(): ?string { return $this->name; } @@ -241,7 +241,7 @@ public function setName($name): File /** * Get the file bucket ID. */ - public function bucketId(): string + public function bucketId(): ?string { return $this->bucketId; } @@ -261,7 +261,7 @@ public function setBucketId($bucketId) /** * Get the file action (type). */ - public function action(): FileActionType + public function action(): ?FileActionType { return $this->action; } @@ -281,7 +281,7 @@ public function setAction(string $action): File /** * Get the file info. */ - public function info(): FileInfo + public function info(): ?FileInfo { return $this->info; } @@ -301,7 +301,7 @@ public function setInfo($info): File /** * Get the file size. */ - public function contentLength(): int + public function contentLength(): ?int { return $this->contentLength; } @@ -321,7 +321,7 @@ public function setContentLength(int $contentLength): File /** * Get the file type. */ - public function contentType(): string + public function contentType(): ?string { return $this->contentType; } @@ -341,7 +341,7 @@ public function setContentType(string $contentType): File /** * Get the file SHA1 checksum. */ - public function contentSha1(): string + public function contentSha1(): ?string { return $this->contentSha1; } @@ -361,7 +361,7 @@ public function setContentSha1(string $contentSha1): File /** * Get the file MD5 hash. */ - public function contentMd5(): string + public function contentMd5(): ?string { return $this->contentMd5; } @@ -381,7 +381,7 @@ public function setContentMd5(string $contentMd5): File /** * Get the UTC timestamp when the file was uploaded. Always `0` if the action is `folder`. */ - public function uploadTimestamp(): int + public function uploadTimestamp(): ?int { return $this->action->isFolder() ? 0 : $this->uploadTimestamp; } @@ -399,7 +399,7 @@ public function setUploadTimestamp(int $uploadTimestamp): File /** * Get the value of retention. */ - public function retention(): array + public function retention(): ?array { return $this->retention; } @@ -419,7 +419,7 @@ public function setRetention(string $retention): File /** * Get the value of legalHold. */ - public function legalHold(): array + public function legalHold(): ?array { return $this->legalHold; } @@ -503,7 +503,7 @@ public function pathInfo(): FilePathInfo public static function fromArray(array $data): File { return new File( - $data[static::ATTRIBUTE_FILE_ID], + $data[static::ATTRIBUTE_FILE_ID] ?? null, $data[static::ATTRIBUTE_FILE_NAME] ?? null, $data[static::ATTRIBUTE_BUCKET_ID] ?? null, $data[static::ATTRIBUTE_ACTION] ?? null, diff --git a/src/Object/File/DownloadOptions.php b/src/Object/File/DownloadOptions.php index d5b7a44..86a12a7 100644 --- a/src/Object/File/DownloadOptions.php +++ b/src/Object/File/DownloadOptions.php @@ -337,8 +337,8 @@ public function toArray() { * * @return string The query string. */ - public function toQueryString() { - return http_build_query([ + public function getDownloadQueryOptions() { + return array_filter([ static::OPTION_AUTHORIZATION => $this->authorization, static::OPTION_CONTENT_DISPOSITION => $this->contentDisposition, static::OPTION_CONTENT_ENCODING => $this->contentEncoding, diff --git a/src/Object/File/ServerSideEncryption.php b/src/Object/File/ServerSideEncryption.php index 72ebe27..3465c4d 100644 --- a/src/Object/File/ServerSideEncryption.php +++ b/src/Object/File/ServerSideEncryption.php @@ -194,8 +194,8 @@ public static function fromArray(array $data, bool $rawKeys = false): ServerSide $customerKeyMd5 = $data[static::ATTRIBUTE_CUSTOMER_KEY_MD5] ?? null; return new ServerSideEncryption( - $data[static::ATTRIBUTE_MODE] ?? static::MODE_CUSTOMER, - $data[static::ATTRIBUTE_ALGORITHM] ?? static::ALGORITHM_AES256, + $data[static::ATTRIBUTE_MODE] ?? null, + $data[static::ATTRIBUTE_ALGORITHM] ?? null, $customerKey ? ($rawKeys ? base64_encode($customerKey) : $customerKey) : null, $customerKeyMd5 ? ($rawKeys ? base64_encode($customerKeyMd5) : $customerKeyMd5) : null ); diff --git a/src/Operations/BucketOperationsTrait.php b/src/Operations/BucketOperationsTrait.php index 18e1dc4..1baf669 100644 --- a/src/Operations/BucketOperationsTrait.php +++ b/src/Operations/BucketOperationsTrait.php @@ -4,7 +4,7 @@ namespace Zaxbux\BackblazeB2\Operations; -use Zaxbux\BackblazeB2\Exceptions\NotFoundException; +use Zaxbux\BackblazeB2\Exceptions\NoResultsException; use Zaxbux\BackblazeB2\Http\Endpoint; use Zaxbux\BackblazeB2\Object\AccountAuthorization; use Zaxbux\BackblazeB2\Object\Bucket; @@ -182,7 +182,7 @@ public function updateBucket( * @param string $bucketId The ID of the bucket to fetch. Defaults to the authorized bucket, if any. * @param array|null $bucketTypes Filter for bucket types returned in the list buckets response. * - * @throws NotFoundException + * @throws NoResultsException */ public function getBucketById( ?string $bucketId = null, @@ -193,7 +193,7 @@ public function getBucketById( $buckets = $response->getArrayCopy(); if (count($buckets) !== 1) { - throw new NotFoundException(sprintf('Bucket "%s" not found.', $bucketId)); + throw new NoResultsException(sprintf('Bucket "%s" not found.', $bucketId)); } return $buckets[0]; @@ -205,7 +205,7 @@ public function getBucketById( * @param string $bucketName The name of the bucket to fetch. * @param array|null $bucketTypes Filter for bucket types returned in the list buckets response. * - * @throws NotFoundException + * @throws NoResultsException */ public function getBucketByName(string $bucketName, array $bucketTypes = null): Bucket { @@ -214,7 +214,7 @@ public function getBucketByName(string $bucketName, array $bucketTypes = null): //$buckets = $response->getArrayCopy(); if (!$response->valid()) { - throw new NotFoundException(sprintf('Bucket "%s" not found.', $bucketName)); + throw new NoResultsException(sprintf('Bucket "%s" not found.', $bucketName)); } return $response->current(); diff --git a/src/Operations/DownloadOperationsTrait.php b/src/Operations/DownloadOperationsTrait.php index d20c31f..fb347bd 100644 --- a/src/Operations/DownloadOperationsTrait.php +++ b/src/Operations/DownloadOperationsTrait.php @@ -77,11 +77,7 @@ public function downloadFileById( ?bool $headersOnly = false ): FileDownload { return DownloadHelper::instance($this)->download( - Utils::joinPaths( - $this->accountAuthorization()->downloadUrl(), - Client::B2_API_VERSION, - Endpoint::DOWNLOAD_FILE_BY_ID - ), + Client::B2_API_VERSION .Endpoint::DOWNLOAD_FILE_BY_ID, [File::ATTRIBUTE_FILE_ID => $fileId], $options, $sink, @@ -114,8 +110,7 @@ public function downloadFileByName( ): FileDownload { return DownloadHelper::instance($this)->download( Utils::joinPaths( - $this->accountAuthorization()->apiUrl(), - 'file', + Endpoint::DOWNLOAD_FILE_BY_NAME, $bucketName ?? $this->allowedBucketName(), $fileName ), diff --git a/src/Operations/FileOperationsTrait.php b/src/Operations/FileOperationsTrait.php index 35f1827..f2917c9 100644 --- a/src/Operations/FileOperationsTrait.php +++ b/src/Operations/FileOperationsTrait.php @@ -4,7 +4,7 @@ namespace Zaxbux\BackblazeB2\Operations; -use Zaxbux\BackblazeB2\Exceptions\NotFoundException; +use Zaxbux\BackblazeB2\Exceptions\NoResultsException; use Zaxbux\BackblazeB2\Http\Endpoint; use Zaxbux\BackblazeB2\Object\AccountAuthorization; use Zaxbux\BackblazeB2\Object\File; @@ -101,7 +101,7 @@ public function deleteFileVersion( $response = $this->http->request('POST', Endpoint::DELETE_FILE_VERSION, [ 'json' => Utils::filterRequestOptions([ File::ATTRIBUTE_FILE_ID => $fileId, - File::ATTRIBUTE_FILE_NAME => $fileName ?? $this->getFileById($fileId)->id(), + File::ATTRIBUTE_FILE_NAME => $fileName ?? $this->getFileInfo($fileId)->name(), ], [ File::ATTRIBUTE_BYPASS_GOVERNANCE => $bypassGovernance, ]), @@ -222,7 +222,7 @@ public function listFileNames( */ public function listFileVersions( ?string $bucketId = null, - ?string $prefix = '', + ?string $prefix = null, ?string $delimiter = null, ?string $startFileName = null, ?string $startFileId = null, @@ -262,7 +262,7 @@ public function updateFileLegalHold( ): File { $response = $this->http->request('POST', Endpoint::UPDATE_FILE_LEGAL_HOLD, [ 'json' => Utils::filterRequestOptions([ - File::ATTRIBUTE_FILE_NAME => $fileName ?? $this->getFileById($fileId)->name(), + File::ATTRIBUTE_FILE_NAME => $fileName ?? $this->getFileInfo($fileId)->name(), File::ATTRIBUTE_FILE_ID => $fileId, File::ATTRIBUTE_LEGAL_HOLD => $legalHold, ]), @@ -293,7 +293,7 @@ public function updateFileRetention( ): File { $response = $this->http->request('POST', Endpoint::UPDATE_FILE_RETENTION, [ 'json' => Utils::filterRequestOptions([ - File::ATTRIBUTE_FILE_NAME => $fileName ?? $this->getFileById($fileId)->id(), + File::ATTRIBUTE_FILE_NAME => $fileName ?? $this->getFileInfo($fileId)->name(), File::ATTRIBUTE_FILE_ID => $fileId, File::ATTRIBUTE_FILE_RETENTION => $fileRetention, File::ATTRIBUTE_BYPASS_GOVERNANCE => $bypassGovernance, @@ -312,7 +312,7 @@ public function updateFileRetention( */ public function listAllFileNames( ?string $bucketId = null, - string $prefix = '', + string $prefix = null, string $delimiter = null, string $startFileName = null ): FileList { @@ -332,7 +332,7 @@ public function listAllFileNames( public function getFileByName(string $fileName, ?string $bucketId = null): File { if (!$file = $this->listFileNames($bucketId, '', null, $fileName, 1)->current()) { - throw new NotFoundException(sprintf('No results returned for file name "%s"', $fileName)); + throw new NoResultsException(sprintf('No results returned for file name "%s"', $fileName)); } return $file; @@ -347,7 +347,7 @@ public function getFileByName(string $fileName, ?string $bucketId = null): File */ public function listAllFileVersions( ?string $bucketId = null, - ?string $prefix = '', + ?string $prefix = null, ?string $delimiter = null, ?string $startFileName = null, ?string $startFileId = null @@ -367,15 +367,6 @@ public function listAllFileVersions( return $allFiles; } - public function getFileById(string $fileId, ?string $bucketId = null): File - { - if (!$file = $this->listFileVersions($bucketId, '', null, null, $fileId, 1)->current()) { - throw new NotFoundException(sprintf('No results returned for file id "%s"', $fileId)); - } - - return $file; - } - /** * Deletes all versions of a file(s) in a bucket. * @@ -391,7 +382,7 @@ public function getFileById(string $fileId, ?string $bucketId = null): File public function deleteAllFileVersions( ?string $startFileId = null, ?string $startFileName = null, - ?string $prefix = '', + ?string $prefix = null, ?string $delimiter = null, ?string $bucketId = null, ?bool $bypassGovernance = false @@ -403,8 +394,8 @@ public function deleteAllFileVersions( while ($fileVersions->valid()) { $deleted->append($this->deleteFileVersion( - $fileVersions->current()->name(), $fileVersions->current()->id(), + $fileVersions->current()->name(), $bypassGovernance )); diff --git a/src/Operations/UploadOperationsTrait.php b/src/Operations/UploadOperationsTrait.php index d8a76c6..4e219f3 100644 --- a/src/Operations/UploadOperationsTrait.php +++ b/src/Operations/UploadOperationsTrait.php @@ -92,7 +92,7 @@ public function uploadFile( 'Content-Type' => $contentType ?? File::CONTENT_TYPE_AUTO, 'Content-Length' => $uploadMetadata->length(), File::HEADER_X_BZ_CONTENT_SHA1 => $uploadMetadata->sha1(), - File::HEADER_X_BZ_FILE_NAME => $fileName, //rawurlencode($fileName),// urlencode($fileName), + File::HEADER_X_BZ_FILE_NAME => urlencode($fileName), ], ($serverSideEncryption->getHeaders() ?? []), ($fileInfo->getHeaders() ?? []) diff --git a/src/Response/FileList.php b/src/Response/FileList.php index e68b48a..3a2f3a6 100644 --- a/src/Response/FileList.php +++ b/src/Response/FileList.php @@ -28,9 +28,10 @@ public function __construct( $this->nextFileName = $nextFileName; } - public function current(): File + public function current(): ?File { $value = parent::current(); + if (!$value) return null; return $value instanceof File ? $value : File::fromArray($value); } @@ -38,7 +39,7 @@ public function current(): File /** * Get the value of nextFileId. */ - public function nextFIleId(): ?string + public function nextFileId(): ?string { return $this->nextFileId; } @@ -46,7 +47,7 @@ public function nextFIleId(): ?string /** * Get the value of nextFileName. */ - public function nextFIleName(): ?string + public function nextFileName(): ?string { return $this->nextFileName; } diff --git a/src/Utils.php b/src/Utils.php index 422c64d..3b3938c 100644 --- a/src/Utils.php +++ b/src/Utils.php @@ -35,6 +35,8 @@ public static function filterRequestOptions(array $required, ...$optional): arra $options = []; foreach ($optional as $set) { + if (!isset($set)) continue; + if (is_array($set)) { // Remove options with NULL values $set += array_filter($set);