PluginProbe
Media Cloud Sync / 1.2.12
Media Cloud Sync v1.2.12
1.4.2 1.4.1 1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 All 36 releases
media-cloud-sync / includes / sdk / s3 / Aws / S3 / ObjectCopier.php

ObjectCopier.php in Media Cloud Sync 1.2.12, at includes/sdk/s3/Aws/S3/ObjectCopier.php

117 lines 5.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Dudlewebs\WPMCS\s3\Aws\S3;
4
5 use Dudlewebs\WPMCS\s3\Aws\Arn\ArnParser;
6 use Dudlewebs\WPMCS\s3\Aws\Arn\S3\AccessPointArn;
7 use Dudlewebs\WPMCS\s3\Aws\Exception\MultipartUploadException;
8 use Dudlewebs\WPMCS\s3\Aws\Result;
9 use Dudlewebs\WPMCS\s3\Aws\S3\Exception\S3Exception;
10 use Dudlewebs\WPMCS\s3\GuzzleHttp\Promise\Coroutine;
11 use Dudlewebs\WPMCS\s3\GuzzleHttp\Promise\PromisorInterface;
12 use InvalidArgumentException;
13 /**
14 * Copies objects from one S3 location to another, utilizing a multipart copy
15 * when appropriate.
16 */
17 class ObjectCopier implements PromisorInterface
18 {
19 const DEFAULT_MULTIPART_THRESHOLD = MultipartUploader::PART_MAX_SIZE;
20 private $client;
21 private $source;
22 private $destination;
23 private $acl;
24 private $options;
25 private static $defaults = ['before_lookup' => null, 'before_upload' => null, 'concurrency' => 5, 'mup_threshold' => self::DEFAULT_MULTIPART_THRESHOLD, 'params' => [], 'part_size' => null, 'version_id' => null];
26 /**
27 * @param S3ClientInterface $client The S3 Client used to execute
28 * the copy command(s).
29 * @param array $source The object to copy, specified as
30 * an array with a 'Bucket' and
31 * 'Key' keys. Provide a
32 * 'VersionID' key to copy a
33 * specified version of an object.
34 * @param array $destination The bucket and key to which to
35 * copy the $source, specified as
36 * an array with a 'Bucket' and
37 * 'Key' keys.
38 * @param string $acl ACL to apply to the copy
39 * (default: private).
40 * @param array $options Options used to configure the
41 * copy process. Options passed in
42 * through 'params' are added to
43 * the sub commands.
44 *
45 * @throws InvalidArgumentException
46 */
47 public function __construct(S3ClientInterface $client, array $source, array $destination, $acl = 'private', array $options = [])
48 {
49 $this->validateLocation($source);
50 $this->validateLocation($destination);
51 $this->client = $client;
52 $this->source = $source;
53 $this->destination = $destination;
54 $this->acl = $acl;
55 $this->options = $options + self::$defaults;
56 }
57 /**
58 * Perform the configured copy asynchronously. Returns a promise that is
59 * fulfilled with the result of the CompleteMultipartUpload or CopyObject
60 * operation or rejected with an exception.
61 *
62 * @return Coroutine
63 */
64 public function promise()
65 {
66 return Coroutine::of(function () {
67 $headObjectCommand = $this->client->getCommand('HeadObject', $this->options['params'] + $this->source);
68 if (\is_callable($this->options['before_lookup'])) {
69 $this->options['before_lookup']($headObjectCommand);
70 }
71 $objectStats = (yield $this->client->executeAsync($headObjectCommand));
72 if ($objectStats['ContentLength'] > $this->options['mup_threshold']) {
73 $mup = new MultipartCopy($this->client, $this->getSourcePath(), ['source_metadata' => $objectStats, 'acl' => $this->acl] + $this->destination + $this->options);
74 (yield $mup->promise());
75 } else {
76 $defaults = ['ACL' => $this->acl, 'MetadataDirective' => 'COPY', 'CopySource' => $this->getSourcePath()];
77 $params = \array_diff_key($this->options, self::$defaults) + $this->destination + $defaults + $this->options['params'];
78 (yield $this->client->executeAsync($this->client->getCommand('CopyObject', $params)));
79 }
80 });
81 }
82 /**
83 * Perform the configured copy synchronously. Returns the result of the
84 * CompleteMultipartUpload or CopyObject operation.
85 *
86 * @return Result
87 *
88 * @throws S3Exception
89 * @throws MultipartUploadException
90 */
91 public function copy()
92 {
93 return $this->promise()->wait();
94 }
95 private function validateLocation(array $location)
96 {
97 if (empty($location['Bucket']) || empty($location['Key'])) {
98 throw new \InvalidArgumentException('Locations provided to an' . ' Aws\\S3\\ObjectCopier must have a non-empty Bucket and Key');
99 }
100 }
101 private function getSourcePath()
102 {
103 if (ArnParser::isArn($this->source['Bucket'])) {
104 try {
105 new AccessPointArn($this->source['Bucket']);
106 } catch (\Exception $e) {
107 throw new \InvalidArgumentException('Provided ARN was a not a valid S3 access point ARN (' . $e->getMessage() . ')', 0, $e);
108 }
109 }
110 $sourcePath = "/{$this->source['Bucket']}/" . \rawurlencode($this->source['Key']);
111 if (isset($this->source['VersionId'])) {
112 $sourcePath .= "?versionId={$this->source['VersionId']}";
113 }
114 return $sourcePath;
115 }
116 }
117