PluginProbe ʕ •ᴥ•ʔ
Transferito: WP Migration / trunk
Transferito: WP Migration vtrunk
trunk 11.4.0 12.0.0 13.1.0 14.0.0 14.0.11 14.0.7 14.1.0 14.1.1 14.1.2 14.1.3 14.1.4
transferito / vendor / aws / aws-sdk-php / src / S3 / S3ClientTrait.php
transferito / vendor / aws / aws-sdk-php / src / S3 Last commit date
Crypto 11 months ago Exception 11 months ago RegionalEndpoint 11 months ago UseArnRegion 11 months ago AmbiguousSuccessParser.php 11 months ago ApplyChecksumMiddleware.php 11 months ago BatchDelete.php 11 months ago BucketEndpointArnMiddleware.php 11 months ago BucketEndpointMiddleware.php 11 months ago CalculatesChecksumTrait.php 11 months ago EndpointRegionHelperTrait.php 11 months ago GetBucketLocationParser.php 11 months ago MultipartCopy.php 11 months ago MultipartUploader.php 11 months ago MultipartUploadingTrait.php 11 months ago ObjectCopier.php 11 months ago ObjectUploader.php 11 months ago PermanentRedirectMiddleware.php 11 months ago PostObject.php 11 months ago PostObjectV4.php 11 months ago PutObjectUrlMiddleware.php 11 months ago RetryableMalformedResponseParser.php 11 months ago S3Client.php 11 months ago S3ClientInterface.php 11 months ago S3ClientTrait.php 11 months ago S3EndpointMiddleware.php 11 months ago S3MultiRegionClient.php 11 months ago S3UriParser.php 11 months ago SSECMiddleware.php 11 months ago StreamWrapper.php 11 months ago Transfer.php 11 months ago ValidateResponseChecksumParser.php 11 months ago
S3ClientTrait.php
400 lines
1 <?php
2 namespace Aws\S3;
3
4 use Aws\Api\Parser\PayloadParserTrait;
5 use Aws\CommandInterface;
6 use Aws\Exception\AwsException;
7 use Aws\HandlerList;
8 use Aws\ResultInterface;
9 use Aws\S3\Exception\PermanentRedirectException;
10 use Aws\S3\Exception\S3Exception;
11 use GuzzleHttp\Promise\PromiseInterface;
12 use GuzzleHttp\Promise\RejectedPromise;
13 use Psr\Http\Message\ResponseInterface;
14
15 /**
16 * A trait providing S3-specific functionality. This is meant to be used in
17 * classes implementing \Aws\S3\S3ClientInterface
18 */
19 trait S3ClientTrait
20 {
21 use PayloadParserTrait;
22
23 /**
24 * @see S3ClientInterface::upload()
25 */
26 public function upload(
27 $bucket,
28 $key,
29 $body,
30 $acl = 'private',
31 array $options = []
32 ) {
33 return $this
34 ->uploadAsync($bucket, $key, $body, $acl, $options)
35 ->wait();
36 }
37
38 /**
39 * @see S3ClientInterface::uploadAsync()
40 */
41 public function uploadAsync(
42 $bucket,
43 $key,
44 $body,
45 $acl = 'private',
46 array $options = []
47 ) {
48 return (new ObjectUploader($this, $bucket, $key, $body, $acl, $options))
49 ->promise();
50 }
51
52 /**
53 * @see S3ClientInterface::copy()
54 */
55 public function copy(
56 $fromB,
57 $fromK,
58 $destB,
59 $destK,
60 $acl = 'private',
61 array $opts = []
62 ) {
63 return $this->copyAsync($fromB, $fromK, $destB, $destK, $acl, $opts)
64 ->wait();
65 }
66
67 /**
68 * @see S3ClientInterface::copyAsync()
69 */
70 public function copyAsync(
71 $fromB,
72 $fromK,
73 $destB,
74 $destK,
75 $acl = 'private',
76 array $opts = []
77 ) {
78 $source = [
79 'Bucket' => $fromB,
80 'Key' => $fromK,
81 ];
82 if (isset($opts['version_id'])) {
83 $source['VersionId'] = $opts['version_id'];
84 }
85 $destination = [
86 'Bucket' => $destB,
87 'Key' => $destK
88 ];
89
90 return (new ObjectCopier($this, $source, $destination, $acl, $opts))
91 ->promise();
92 }
93
94 /**
95 * @see S3ClientInterface::registerStreamWrapper()
96 */
97 public function registerStreamWrapper()
98 {
99 StreamWrapper::register($this);
100 }
101
102 /**
103 * @see S3ClientInterface::registerStreamWrapperV2()
104 */
105 public function registerStreamWrapperV2()
106 {
107 StreamWrapper::register(
108 $this,
109 's3',
110 null,
111 true
112 );
113 }
114
115 /**
116 * @see S3ClientInterface::deleteMatchingObjects()
117 */
118 public function deleteMatchingObjects(
119 $bucket,
120 $prefix = '',
121 $regex = '',
122 array $options = []
123 ) {
124 $this->deleteMatchingObjectsAsync($bucket, $prefix, $regex, $options)
125 ->wait();
126 }
127
128 /**
129 * @see S3ClientInterface::deleteMatchingObjectsAsync()
130 */
131 public function deleteMatchingObjectsAsync(
132 $bucket,
133 $prefix = '',
134 $regex = '',
135 array $options = []
136 ) {
137 if (!$prefix && !$regex) {
138 return new RejectedPromise(
139 new \RuntimeException('A prefix or regex is required.')
140 );
141 }
142
143 $params = ['Bucket' => $bucket, 'Prefix' => $prefix];
144 $iter = $this->getIterator('ListObjects', $params);
145
146 if ($regex) {
147 $iter = \Aws\filter($iter, function ($c) use ($regex) {
148 return preg_match($regex, $c['Key']);
149 });
150 }
151
152 return BatchDelete::fromIterator($this, $bucket, $iter, $options)
153 ->promise();
154 }
155
156 /**
157 * @see S3ClientInterface::uploadDirectory()
158 */
159 public function uploadDirectory(
160 $directory,
161 $bucket,
162 $keyPrefix = null,
163 array $options = []
164 ) {
165 $this->uploadDirectoryAsync($directory, $bucket, $keyPrefix, $options)
166 ->wait();
167 }
168
169 /**
170 * @see S3ClientInterface::uploadDirectoryAsync()
171 */
172 public function uploadDirectoryAsync(
173 $directory,
174 $bucket,
175 $keyPrefix = null,
176 array $options = []
177 ) {
178 $d = "s3://$bucket" . ($keyPrefix ? '/' . ltrim($keyPrefix, '/') : '');
179 return (new Transfer($this, $directory, $d, $options))->promise();
180 }
181
182 /**
183 * @see S3ClientInterface::downloadBucket()
184 */
185 public function downloadBucket(
186 $directory,
187 $bucket,
188 $keyPrefix = '',
189 array $options = []
190 ) {
191 $this->downloadBucketAsync($directory, $bucket, $keyPrefix, $options)
192 ->wait();
193 }
194
195 /**
196 * @see S3ClientInterface::downloadBucketAsync()
197 */
198 public function downloadBucketAsync(
199 $directory,
200 $bucket,
201 $keyPrefix = '',
202 array $options = []
203 ) {
204 $s = "s3://$bucket" . ($keyPrefix ? '/' . ltrim($keyPrefix, '/') : '');
205 return (new Transfer($this, $s, $directory, $options))->promise();
206 }
207
208 /**
209 * @see S3ClientInterface::determineBucketRegion()
210 */
211 public function determineBucketRegion($bucketName)
212 {
213 return $this->determineBucketRegionAsync($bucketName)->wait();
214 }
215
216 /**
217 * @see S3ClientInterface::determineBucketRegionAsync()
218 *
219 * @param string $bucketName
220 *
221 * @return PromiseInterface
222 */
223 public function determineBucketRegionAsync($bucketName)
224 {
225 $command = $this->getCommand('HeadBucket', ['Bucket' => $bucketName]);
226 $handlerList = clone $this->getHandlerList();
227 $handlerList->remove('s3.permanent_redirect');
228 $handlerList->remove('signer');
229 $handler = $handlerList->resolve();
230
231 return $handler($command)
232 ->then(static function (ResultInterface $result) {
233 return $result['@metadata']['headers']['x-amz-bucket-region'];
234 }, function (AwsException $e) {
235 $response = $e->getResponse();
236 if ($response === null) {
237 throw $e;
238 }
239
240 if ($e->getAwsErrorCode() === 'AuthorizationHeaderMalformed') {
241 $region = $this->determineBucketRegionFromExceptionBody(
242 $response
243 );
244 if (!empty($region)) {
245 return $region;
246 }
247 throw $e;
248 }
249
250 return $response->getHeaderLine('x-amz-bucket-region');
251 });
252 }
253
254 private function determineBucketRegionFromExceptionBody(ResponseInterface $response)
255 {
256 try {
257 $element = $this->parseXml($response->getBody(), $response);
258 if (!empty($element->Region)) {
259 return (string)$element->Region;
260 }
261 } catch (\Exception $e) {
262 // Fallthrough on exceptions from parsing
263 }
264 return false;
265 }
266
267 /**
268 * @see S3ClientInterface::doesBucketExist()
269 */
270 public function doesBucketExist($bucket)
271 {
272 return $this->checkExistenceWithCommand(
273 $this->getCommand('HeadBucket', ['Bucket' => $bucket])
274 );
275 }
276
277 /**
278 * @see S3ClientInterface::doesBucketExistV2()
279 */
280 public function doesBucketExistV2($bucket, $accept403 = false)
281 {
282 $command = $this->getCommand('HeadBucket', ['Bucket' => $bucket]);
283
284 try {
285 $this->execute($command);
286 return true;
287 } catch (S3Exception $e) {
288 if (
289 ($accept403 && $e->getStatusCode() === 403)
290 || $e instanceof PermanentRedirectException
291 ) {
292 return true;
293 }
294 if ($e->getStatusCode() === 404) {
295 return false;
296 }
297 throw $e;
298 }
299 }
300
301 /**
302 * @see S3ClientInterface::doesObjectExist()
303 */
304 public function doesObjectExist($bucket, $key, array $options = [])
305 {
306 return $this->checkExistenceWithCommand(
307 $this->getCommand('HeadObject', [
308 'Bucket' => $bucket,
309 'Key' => $key
310 ] + $options)
311 );
312 }
313
314 /**
315 * @see S3ClientInterface::doesObjectExistV2()
316 */
317 public function doesObjectExistV2(
318 $bucket,
319 $key,
320 $includeDeleteMarkers = false,
321 array $options = []
322 ){
323 $command = $this->getCommand('HeadObject', [
324 'Bucket' => $bucket,
325 'Key' => $key
326 ] + $options
327 );
328
329 try {
330 $this->execute($command);
331 return true;
332 } catch (S3Exception $e) {
333 if ($includeDeleteMarkers
334 && $this->useDeleteMarkers($e)
335 ) {
336 return true;
337 }
338 if ($e->getStatusCode() === 404) {
339 return false;
340 }
341 throw $e;
342 }
343 }
344
345 private function useDeleteMarkers($exception)
346 {
347 $response = $exception->getResponse();
348 return !empty($response)
349 && $response->getHeader('x-amz-delete-marker');
350 }
351
352 /**
353 * Determines whether or not a resource exists using a command
354 *
355 * @param CommandInterface $command Command used to poll for the resource
356 *
357 * @return bool
358 * @throws S3Exception|\Exception if there is an unhandled exception
359 */
360 private function checkExistenceWithCommand(CommandInterface $command)
361 {
362 try {
363 $this->execute($command);
364 return true;
365 } catch (S3Exception $e) {
366 if ($e->getAwsErrorCode() == 'AccessDenied') {
367 return true;
368 }
369 if ($e->getStatusCode() >= 500) {
370 throw $e;
371 }
372 return false;
373 }
374 }
375
376 /**
377 * @see S3ClientInterface::execute()
378 */
379 abstract public function execute(CommandInterface $command);
380
381 /**
382 * @see S3ClientInterface::getCommand()
383 */
384 abstract public function getCommand($name, array $args = []);
385
386 /**
387 * @see S3ClientInterface::getHandlerList()
388 *
389 * @return HandlerList
390 */
391 abstract public function getHandlerList();
392
393 /**
394 * @see S3ClientInterface::getIterator()
395 *
396 * @return \Iterator
397 */
398 abstract public function getIterator($name, array $args = []);
399 }
400