From 7b9cbfd2fdadb9c92b77f79dd4f00dc35f05978f Mon Sep 17 00:00:00 2001 From: AsyncAws <61784373+async-aws-bot@users.noreply.github.com> Date: Fri, 22 Nov 2024 04:21:26 -0800 Subject: [PATCH] Update generated code (#1806) update generated code --- CHANGELOG.md | 1 + .../EncryptionTypeMismatchException.php | 13 +++ src/Exception/InvalidRequestException.php | 17 ++++ src/Exception/InvalidWriteOffsetException.php | 12 +++ src/Exception/TooManyPartsException.php | 13 +++ src/Input/AbortMultipartUploadRequest.php | 30 ++++++ src/Input/DeleteObjectRequest.php | 94 +++++++++++++++++++ src/Input/PutObjectRequest.php | 29 ++++++ src/Result/PutObjectOutput.php | 18 ++++ src/S3Client.php | 61 +++++++----- src/ValueObject/ObjectIdentifier.php | 61 ++++++++++++ 11 files changed, 328 insertions(+), 21 deletions(-) create mode 100644 src/Exception/EncryptionTypeMismatchException.php create mode 100644 src/Exception/InvalidRequestException.php create mode 100644 src/Exception/InvalidWriteOffsetException.php create mode 100644 src/Exception/TooManyPartsException.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 0041b86..63f99ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Added - AWS api-change: Add support for the new optional bucket-region and prefix query parameters in the ListBuckets API. For ListBuckets requests that express pagination, Amazon S3 will now return both the bucket names and associated AWS regions in the response. +- AWS api-change: Add support for conditional deletes for the S3 DeleteObject and DeleteObjects APIs. Add support for write offset bytes option used to append to objects with the S3 PutObject API. ### Changed diff --git a/src/Exception/EncryptionTypeMismatchException.php b/src/Exception/EncryptionTypeMismatchException.php new file mode 100644 index 0000000..abb53d8 --- /dev/null +++ b/src/Exception/EncryptionTypeMismatchException.php @@ -0,0 +1,13 @@ + This functionality is only supported for directory buckets. + * + * @var \DateTimeImmutable|null + */ + private $ifMatchInitiatedTime; + /** * @param array{ * Bucket?: string, @@ -82,6 +94,7 @@ final class AbortMultipartUploadRequest extends Input * UploadId?: string, * RequestPayer?: null|RequestPayer::*, * ExpectedBucketOwner?: null|string, + * IfMatchInitiatedTime?: null|\DateTimeImmutable|string, * '@region'?: string|null, * } $input */ @@ -92,6 +105,7 @@ public function __construct(array $input = []) $this->uploadId = $input['UploadId'] ?? null; $this->requestPayer = $input['RequestPayer'] ?? null; $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->ifMatchInitiatedTime = !isset($input['IfMatchInitiatedTime']) ? null : ($input['IfMatchInitiatedTime'] instanceof \DateTimeImmutable ? $input['IfMatchInitiatedTime'] : new \DateTimeImmutable($input['IfMatchInitiatedTime'])); parent::__construct($input); } @@ -102,6 +116,7 @@ public function __construct(array $input = []) * UploadId?: string, * RequestPayer?: null|RequestPayer::*, * ExpectedBucketOwner?: null|string, + * IfMatchInitiatedTime?: null|\DateTimeImmutable|string, * '@region'?: string|null, * }|AbortMultipartUploadRequest $input */ @@ -120,6 +135,11 @@ public function getExpectedBucketOwner(): ?string return $this->expectedBucketOwner; } + public function getIfMatchInitiatedTime(): ?\DateTimeImmutable + { + return $this->ifMatchInitiatedTime; + } + public function getKey(): ?string { return $this->key; @@ -154,6 +174,9 @@ public function request(): Request if (null !== $this->expectedBucketOwner) { $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; } + if (null !== $this->ifMatchInitiatedTime) { + $headers['x-amz-if-match-initiated-time'] = $this->ifMatchInitiatedTime->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } // Prepare query $query = []; @@ -195,6 +218,13 @@ public function setExpectedBucketOwner(?string $value): self return $this; } + public function setIfMatchInitiatedTime(?\DateTimeImmutable $value): self + { + $this->ifMatchInitiatedTime = $value; + + return $this; + } + public function setKey(?string $value): self { $this->key = $value; diff --git a/src/Input/DeleteObjectRequest.php b/src/Input/DeleteObjectRequest.php index e806d24..59ad115 100644 --- a/src/Input/DeleteObjectRequest.php +++ b/src/Input/DeleteObjectRequest.php @@ -96,6 +96,46 @@ final class DeleteObjectRequest extends Input */ private $expectedBucketOwner; + /** + * The `If-Match` header field makes the request method conditional on ETags. If the ETag value does not match, the + * operation returns a `412 Precondition Failed` error. If the ETag matches or if the object doesn't exist, the + * operation will return a `204 Success (No Content) response`. + * + * For more information about conditional requests, see RFC 7232 [^1]. + * + * > This functionality is only supported for directory buckets. + * + * [^1]: https://docs.aws.amazon.com/https:/tools.ietf.org/html/rfc7232 + * + * @var string|null + */ + private $ifMatch; + + /** + * If present, the object is deleted only if its modification times matches the provided `Timestamp`. If the `Timestamp` + * values do not match, the operation returns a `412 Precondition Failed` error. If the `Timestamp` matches or if the + * object doesn’t exist, the operation returns a `204 Success (No Content)` response. + * + * > This functionality is only supported for directory buckets. + * + * @var \DateTimeImmutable|null + */ + private $ifMatchLastModifiedTime; + + /** + * If present, the object is deleted only if its size matches the provided size in bytes. If the `Size` value does not + * match, the operation returns a `412 Precondition Failed` error. If the `Size` matches or if the object doesn’t + * exist, the operation returns a `204 Success (No Content)` response. + * + * > This functionality is only supported for directory buckets. + * + * ! You can use the `If-Match`, `x-amz-if-match-last-modified-time` and `x-amz-if-match-size` conditional headers in + * ! conjunction with each-other or individually. + * + * @var int|null + */ + private $ifMatchSize; + /** * @param array{ * Bucket?: string, @@ -105,6 +145,9 @@ final class DeleteObjectRequest extends Input * RequestPayer?: null|RequestPayer::*, * BypassGovernanceRetention?: null|bool, * ExpectedBucketOwner?: null|string, + * IfMatch?: null|string, + * IfMatchLastModifiedTime?: null|\DateTimeImmutable|string, + * IfMatchSize?: null|int, * '@region'?: string|null, * } $input */ @@ -117,6 +160,9 @@ public function __construct(array $input = []) $this->requestPayer = $input['RequestPayer'] ?? null; $this->bypassGovernanceRetention = $input['BypassGovernanceRetention'] ?? null; $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->ifMatch = $input['IfMatch'] ?? null; + $this->ifMatchLastModifiedTime = !isset($input['IfMatchLastModifiedTime']) ? null : ($input['IfMatchLastModifiedTime'] instanceof \DateTimeImmutable ? $input['IfMatchLastModifiedTime'] : new \DateTimeImmutable($input['IfMatchLastModifiedTime'])); + $this->ifMatchSize = $input['IfMatchSize'] ?? null; parent::__construct($input); } @@ -129,6 +175,9 @@ public function __construct(array $input = []) * RequestPayer?: null|RequestPayer::*, * BypassGovernanceRetention?: null|bool, * ExpectedBucketOwner?: null|string, + * IfMatch?: null|string, + * IfMatchLastModifiedTime?: null|\DateTimeImmutable|string, + * IfMatchSize?: null|int, * '@region'?: string|null, * }|DeleteObjectRequest $input */ @@ -152,6 +201,21 @@ public function getExpectedBucketOwner(): ?string return $this->expectedBucketOwner; } + public function getIfMatch(): ?string + { + return $this->ifMatch; + } + + public function getIfMatchLastModifiedTime(): ?\DateTimeImmutable + { + return $this->ifMatchLastModifiedTime; + } + + public function getIfMatchSize(): ?int + { + return $this->ifMatchSize; + } + public function getKey(): ?string { return $this->key; @@ -197,6 +261,15 @@ public function request(): Request if (null !== $this->expectedBucketOwner) { $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; } + if (null !== $this->ifMatch) { + $headers['If-Match'] = $this->ifMatch; + } + if (null !== $this->ifMatchLastModifiedTime) { + $headers['x-amz-if-match-last-modified-time'] = $this->ifMatchLastModifiedTime->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->ifMatchSize) { + $headers['x-amz-if-match-size'] = (string) $this->ifMatchSize; + } // Prepare query $query = []; @@ -244,6 +317,27 @@ public function setExpectedBucketOwner(?string $value): self return $this; } + public function setIfMatch(?string $value): self + { + $this->ifMatch = $value; + + return $this; + } + + public function setIfMatchLastModifiedTime(?\DateTimeImmutable $value): self + { + $this->ifMatchLastModifiedTime = $value; + + return $this; + } + + public function setIfMatchSize(?int $value): self + { + $this->ifMatchSize = $value; + + return $this; + } + public function setKey(?string $value): self { $this->key = $value; diff --git a/src/Input/PutObjectRequest.php b/src/Input/PutObjectRequest.php index 99e4489..6677691 100644 --- a/src/Input/PutObjectRequest.php +++ b/src/Input/PutObjectRequest.php @@ -323,6 +323,17 @@ final class PutObjectRequest extends Input */ private $key; + /** + * Specifies the offset for appending data to existing objects in bytes. The offset must be equal to the size of the + * existing object being appended to. If no object exists, setting this header to 0 will create a new object. + * + * > This functionality is only supported for objects in the Amazon S3 Express One Zone storage class in directory + * > buckets. + * + * @var int|null + */ + private $writeOffsetBytes; + /** * A map of metadata to store with the object in S3. * @@ -592,6 +603,7 @@ final class PutObjectRequest extends Input * GrantReadACP?: null|string, * GrantWriteACP?: null|string, * Key?: string, + * WriteOffsetBytes?: null|int, * Metadata?: null|array, * ServerSideEncryption?: null|ServerSideEncryption::*, * StorageClass?: null|StorageClass::*, @@ -635,6 +647,7 @@ public function __construct(array $input = []) $this->grantReadAcp = $input['GrantReadACP'] ?? null; $this->grantWriteAcp = $input['GrantWriteACP'] ?? null; $this->key = $input['Key'] ?? null; + $this->writeOffsetBytes = $input['WriteOffsetBytes'] ?? null; $this->metadata = $input['Metadata'] ?? null; $this->serverSideEncryption = $input['ServerSideEncryption'] ?? null; $this->storageClass = $input['StorageClass'] ?? null; @@ -678,6 +691,7 @@ public function __construct(array $input = []) * GrantReadACP?: null|string, * GrantWriteACP?: null|string, * Key?: string, + * WriteOffsetBytes?: null|int, * Metadata?: null|array, * ServerSideEncryption?: null|ServerSideEncryption::*, * StorageClass?: null|StorageClass::*, @@ -919,6 +933,11 @@ public function getWebsiteRedirectLocation(): ?string return $this->websiteRedirectLocation; } + public function getWriteOffsetBytes(): ?int + { + return $this->writeOffsetBytes; + } + /** * @internal */ @@ -989,6 +1008,9 @@ public function request(): Request if (null !== $this->grantWriteAcp) { $headers['x-amz-grant-write-acp'] = $this->grantWriteAcp; } + if (null !== $this->writeOffsetBytes) { + $headers['x-amz-write-offset-bytes'] = (string) $this->writeOffsetBytes; + } if (null !== $this->serverSideEncryption) { if (!ServerSideEncryption::exists($this->serverSideEncryption)) { throw new InvalidArgument(\sprintf('Invalid parameter "ServerSideEncryption" for "%s". The value "%s" is not a valid "ServerSideEncryption".', __CLASS__, $this->serverSideEncryption)); @@ -1369,4 +1391,11 @@ public function setWebsiteRedirectLocation(?string $value): self return $this; } + + public function setWriteOffsetBytes(?int $value): self + { + $this->writeOffsetBytes = $value; + + return $this; + } } diff --git a/src/Result/PutObjectOutput.php b/src/Result/PutObjectOutput.php index 63afc43..704d459 100644 --- a/src/Result/PutObjectOutput.php +++ b/src/Result/PutObjectOutput.php @@ -157,6 +157,16 @@ class PutObjectOutput extends Result */ private $bucketKeyEnabled; + /** + * The size of the object in bytes. This will only be present if you append to an object. + * + * > This functionality is only supported for objects in the Amazon S3 Express One Zone storage class in directory + * > buckets. + * + * @var int|null + */ + private $size; + /** * @var RequestCharged::*|null */ @@ -231,6 +241,13 @@ public function getServerSideEncryption(): ?string return $this->serverSideEncryption; } + public function getSize(): ?int + { + $this->initialize(); + + return $this->size; + } + public function getSseCustomerAlgorithm(): ?string { $this->initialize(); @@ -283,6 +300,7 @@ protected function populateResult(Response $response): void $this->sseKmsKeyId = $headers['x-amz-server-side-encryption-aws-kms-key-id'][0] ?? null; $this->sseKmsEncryptionContext = $headers['x-amz-server-side-encryption-context'][0] ?? null; $this->bucketKeyEnabled = isset($headers['x-amz-server-side-encryption-bucket-key-enabled'][0]) ? filter_var($headers['x-amz-server-side-encryption-bucket-key-enabled'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->size = isset($headers['x-amz-object-size'][0]) ? (int) $headers['x-amz-object-size'][0] : null; $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; } } diff --git a/src/S3Client.php b/src/S3Client.php index c5f095f..d65fda8 100644 --- a/src/S3Client.php +++ b/src/S3Client.php @@ -24,11 +24,15 @@ use AsyncAws\S3\Enum\TaggingDirective; use AsyncAws\S3\Exception\BucketAlreadyExistsException; use AsyncAws\S3\Exception\BucketAlreadyOwnedByYouException; +use AsyncAws\S3\Exception\EncryptionTypeMismatchException; use AsyncAws\S3\Exception\InvalidObjectStateException; +use AsyncAws\S3\Exception\InvalidRequestException; +use AsyncAws\S3\Exception\InvalidWriteOffsetException; use AsyncAws\S3\Exception\NoSuchBucketException; use AsyncAws\S3\Exception\NoSuchKeyException; use AsyncAws\S3\Exception\NoSuchUploadException; use AsyncAws\S3\Exception\ObjectNotInActiveTierErrorException; +use AsyncAws\S3\Exception\TooManyPartsException; use AsyncAws\S3\Input\AbortMultipartUploadRequest; use AsyncAws\S3\Input\CompleteMultipartUploadRequest; use AsyncAws\S3\Input\CopyObjectRequest; @@ -165,6 +169,7 @@ class S3Client extends AbstractApi * UploadId: string, * RequestPayer?: null|RequestPayer::*, * ExpectedBucketOwner?: null|string, + * IfMatchInitiatedTime?: null|\DateTimeImmutable|string, * '@region'?: string|null, * }|AbortMultipartUploadRequest $input * @@ -938,7 +943,7 @@ public function deleteBucket($input): Result } /** - * > This operation is not supported by directory buckets. + * > This operation is not supported for directory buckets. * * Deletes the `cors` configuration information set for the bucket. * @@ -1039,6 +1044,9 @@ public function deleteBucketCors($input): Result * RequestPayer?: null|RequestPayer::*, * BypassGovernanceRetention?: null|bool, * ExpectedBucketOwner?: null|string, + * IfMatch?: null|string, + * IfMatchLastModifiedTime?: null|\DateTimeImmutable|string, + * IfMatchSize?: null|int, * '@region'?: string|null, * }|DeleteObjectRequest $input */ @@ -1051,7 +1059,7 @@ public function deleteObject($input): DeleteObjectOutput } /** - * > This operation is not supported by directory buckets. + * > This operation is not supported for directory buckets. * * Removes the entire tag set from the specified object. For more information about managing object tags, see Object * Tagging [^1]. @@ -1193,7 +1201,7 @@ public function deleteObjects($input): DeleteObjectsOutput } /** - * > This operation is not supported by directory buckets. + * > This operation is not supported for directory buckets. * * Returns the Cross-Origin Resource Sharing (CORS) configuration information set for the bucket. * @@ -1460,7 +1468,7 @@ public function getObject($input): GetObjectOutput } /** - * > This operation is not supported by directory buckets. + * > This operation is not supported for directory buckets. * * Returns the access control list (ACL) of an object. To use this operation, you must have `s3:GetObjectAcl` * permissions or `READ_ACP` access to the object. For more information, see Mapping of ACL permissions and access @@ -1515,7 +1523,7 @@ public function getObjectAcl($input): GetObjectAclOutput } /** - * > This operation is not supported by directory buckets. + * > This operation is not supported for directory buckets. * * Returns the tag-set of an object. You send the GET request against the tagging subresource associated with the * object. @@ -1634,7 +1642,7 @@ public function getObjectTagging($input): GetObjectTaggingOutput * - If the specified version is a delete marker, the response returns a `405 Method Not Allowed` error and the * `Last-Modified: timestamp` response header. * - * > - **Directory buckets** - Delete marker is not supported by directory buckets. + * > - **Directory buckets** - Delete marker is not supported for directory buckets. * > - **Directory buckets** - S3 Versioning isn't enabled and supported for directory buckets. For this API * > operation, only the `null` value of the version ID is supported by directory buckets. You can only specify * > `null` to the `versionId` query parameter in the request. @@ -1709,18 +1717,18 @@ public function headObject($input): HeadObjectOutput } /** - * > This operation is not supported by directory buckets. + * > This operation is not supported for directory buckets. * - * Returns a list of all buckets owned by the authenticated sender of the request. To use this operation, you must have - * the `s3:ListAllMyBuckets` permission. + * Returns a list of all buckets owned by the authenticated sender of the request. To grant IAM permission to use this + * operation, you must add the `s3:ListAllMyBuckets` policy action. * * For information about Amazon S3 buckets, see Creating, configuring, and working with Amazon S3 buckets [^1]. * - * ! We strongly recommend using only paginated requests. Unpaginated requests are only supported for Amazon Web - * ! Services accounts set to the default general purpose bucket quota of 10,000. If you have an approved general - * ! purpose bucket quota above 10,000, you must send paginated requests to list your account’s buckets. All - * ! unpaginated ListBuckets requests will be rejected for Amazon Web Services accounts with a general purpose bucket - * ! quota greater than 10,000. + * ! We strongly recommend using only paginated `ListBuckets` requests. Unpaginated `ListBuckets` requests are only + * ! supported for Amazon Web Services accounts set to the default general purpose bucket quota of 10,000. If you have + * ! an approved general purpose bucket quota above 10,000, you must send paginated `ListBuckets` requests to list your + * ! account’s buckets. All unpaginated `ListBuckets` requests will be rejected for Amazon Web Services accounts with + * ! a general purpose bucket quota greater than 10,000. * * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/creating-buckets-s3.html * @@ -1849,7 +1857,7 @@ public function listMultipartUploads($input): ListMultipartUploadsOutput } /** - * > This operation is not supported by directory buckets. + * > This operation is not supported for directory buckets. * * Returns metadata about all versions of the objects in a bucket. You can also use request parameters as selection * criteria to return metadata about a subset of all the object versions. @@ -2162,7 +2170,7 @@ public function objectNotExists($input): ObjectNotExistsWaiter } /** - * > This operation is not supported by directory buckets. + * > This operation is not supported for directory buckets. * * Sets the `cors` configuration for your bucket. If the configuration exists, Amazon S3 replaces it. * @@ -2222,7 +2230,7 @@ public function putBucketCors($input): Result } /** - * > This operation is not supported by directory buckets. + * > This operation is not supported for directory buckets. * * Enables notifications of specified events for a bucket. For more information about event notifications, see * Configuring Event Notifications [^1]. @@ -2293,7 +2301,7 @@ public function putBucketNotificationConfiguration($input): Result } /** - * > This operation is not supported by directory buckets. + * > This operation is not supported for directory buckets. * * Sets the tags for a bucket. * @@ -2465,6 +2473,7 @@ public function putBucketTagging($input): Result * GrantReadACP?: null|string, * GrantWriteACP?: null|string, * Key: string, + * WriteOffsetBytes?: null|int, * Metadata?: null|array, * ServerSideEncryption?: null|ServerSideEncryption::*, * StorageClass?: null|StorageClass::*, @@ -2483,17 +2492,27 @@ public function putBucketTagging($input): Result * ExpectedBucketOwner?: null|string, * '@region'?: string|null, * }|PutObjectRequest $input + * + * @throws InvalidRequestException + * @throws InvalidWriteOffsetException + * @throws TooManyPartsException + * @throws EncryptionTypeMismatchException */ public function putObject($input): PutObjectOutput { $input = PutObjectRequest::create($input); - $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'PutObject', 'region' => $input->getRegion()])); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'PutObject', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'InvalidRequest' => InvalidRequestException::class, + 'InvalidWriteOffset' => InvalidWriteOffsetException::class, + 'TooManyParts' => TooManyPartsException::class, + 'EncryptionTypeMismatch' => EncryptionTypeMismatchException::class, + ]])); return new PutObjectOutput($response); } /** - * > This operation is not supported by directory buckets. + * > This operation is not supported for directory buckets. * * Uses the `acl` subresource to set the access control list (ACL) permissions for a new or existing object in an S3 * bucket. You must have the `WRITE_ACP` permission to set the ACL of an object. For more information, see What @@ -2647,7 +2666,7 @@ public function putObjectAcl($input): PutObjectAclOutput } /** - * > This operation is not supported by directory buckets. + * > This operation is not supported for directory buckets. * * Sets the supplied tag-set to an object that already exists in a bucket. A tag is a key-value pair. For more * information, see Object Tagging [^1]. diff --git a/src/ValueObject/ObjectIdentifier.php b/src/ValueObject/ObjectIdentifier.php index 9c5fc83..1798ab2 100644 --- a/src/ValueObject/ObjectIdentifier.php +++ b/src/ValueObject/ObjectIdentifier.php @@ -30,22 +30,59 @@ final class ObjectIdentifier */ private $versionId; + /** + * An entity tag (ETag) is an identifier assigned by a web server to a specific version of a resource found at a URL. + * This header field makes the request method conditional on `ETags`. + * + * > Entity tags (ETags) for S3 Express One Zone are random alphanumeric strings unique to the object. + * + * @var string|null + */ + private $etag; + + /** + * If present, the objects are deleted only if its modification times matches the provided `Timestamp`. + * + * > This functionality is only supported for directory buckets. + * + * @var \DateTimeImmutable|null + */ + private $lastModifiedTime; + + /** + * If present, the objects are deleted only if its size matches the provided size in bytes. + * + * > This functionality is only supported for directory buckets. + * + * @var int|null + */ + private $size; + /** * @param array{ * Key: string, * VersionId?: null|string, + * ETag?: null|string, + * LastModifiedTime?: null|\DateTimeImmutable, + * Size?: null|int, * } $input */ public function __construct(array $input) { $this->key = $input['Key'] ?? $this->throwException(new InvalidArgument('Missing required field "Key".')); $this->versionId = $input['VersionId'] ?? null; + $this->etag = $input['ETag'] ?? null; + $this->lastModifiedTime = $input['LastModifiedTime'] ?? null; + $this->size = $input['Size'] ?? null; } /** * @param array{ * Key: string, * VersionId?: null|string, + * ETag?: null|string, + * LastModifiedTime?: null|\DateTimeImmutable, + * Size?: null|int, * }|ObjectIdentifier $input */ public static function create($input): self @@ -53,11 +90,26 @@ public static function create($input): self return $input instanceof self ? $input : new self($input); } + public function getEtag(): ?string + { + return $this->etag; + } + public function getKey(): string { return $this->key; } + public function getLastModifiedTime(): ?\DateTimeImmutable + { + return $this->lastModifiedTime; + } + + public function getSize(): ?int + { + return $this->size; + } + public function getVersionId(): ?string { return $this->versionId; @@ -73,6 +125,15 @@ public function requestBody(\DOMElement $node, \DOMDocument $document): void if (null !== $v = $this->versionId) { $node->appendChild($document->createElement('VersionId', $v)); } + if (null !== $v = $this->etag) { + $node->appendChild($document->createElement('ETag', $v)); + } + if (null !== $v = $this->lastModifiedTime) { + $node->appendChild($document->createElement('LastModifiedTime', $v->format(\DateTimeInterface::RFC822))); + } + if (null !== $v = $this->size) { + $node->appendChild($document->createElement('Size', (string) $v)); + } } /**