UploadSyncBuilder.php
5.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
<?php
/**
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
namespace Aws\S3\Sync;
use FilesystemIterator as FI;
use Aws\Common\Model\MultipartUpload\AbstractTransfer;
use Aws\S3\Model\Acp;
use Guzzle\Common\HasDispatcherInterface;
use Guzzle\Common\Event;
use Guzzle\Service\Command\CommandInterface;
class UploadSyncBuilder extends AbstractSyncBuilder
{
/** @var string|Acp Access control policy to set on each object */
protected $acp = 'private';
/** @var int */
protected $multipartUploadSize;
/**
* Set the path that contains files to recursively upload to Amazon S3
*
* @param string $path Path that contains files to upload
*
* @return $this
*/
public function uploadFromDirectory($path)
{
$this->baseDir = realpath($path);
$this->sourceIterator = $this->filterIterator(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(
$path,
FI::SKIP_DOTS | FI::UNIX_PATHS | FI::FOLLOW_SYMLINKS
)));
return $this;
}
/**
* Set a glob expression that will match files to upload to Amazon S3
*
* @param string $glob Glob expression
*
* @return $this
* @link http://www.php.net/manual/en/function.glob.php
*/
public function uploadFromGlob($glob)
{
$this->sourceIterator = $this->filterIterator(
new \GlobIterator($glob, FI::SKIP_DOTS | FI::UNIX_PATHS | FI::FOLLOW_SYMLINKS)
);
return $this;
}
/**
* Set a canned ACL to apply to each uploaded object
*
* @param string $acl Canned ACL for each upload
*
* @return $this
*/
public function setAcl($acl)
{
$this->acp = $acl;
return $this;
}
/**
* Set an Access Control Policy to apply to each uploaded object
*
* @param Acp $acp Access control policy
*
* @return $this
*/
public function setAcp(Acp $acp)
{
$this->acp = $acp;
return $this;
}
/**
* Set the multipart upload size threshold. When the size of a file exceeds this value, the file will be uploaded
* using a multipart upload.
*
* @param int $size Size threshold
*
* @return $this
*/
public function setMultipartUploadSize($size)
{
$this->multipartUploadSize = $size;
return $this;
}
protected function specificBuild()
{
$sync = new UploadSync(array(
'client' => $this->client,
'bucket' => $this->bucket,
'iterator' => $this->sourceIterator,
'source_converter' => $this->sourceConverter,
'target_converter' => $this->targetConverter,
'concurrency' => $this->concurrency,
'multipart_upload_size' => $this->multipartUploadSize,
'acl' => $this->acp
));
return $sync;
}
protected function addCustomParamListener(HasDispatcherInterface $sync)
{
// Handle the special multi-part upload event
parent::addCustomParamListener($sync);
$params = $this->params;
$sync->getEventDispatcher()->addListener(
UploadSync::BEFORE_MULTIPART_BUILD,
function (Event $e) use ($params) {
foreach ($params as $k => $v) {
$e['builder']->setOption($k, $v);
}
}
);
}
protected function getTargetIterator()
{
return $this->createS3Iterator();
}
protected function getDefaultSourceConverter()
{
return new KeyConverter($this->baseDir, $this->keyPrefix . $this->delimiter, $this->delimiter);
}
protected function getDefaultTargetConverter()
{
return new KeyConverter('s3://' . $this->bucket . '/', '', DIRECTORY_SEPARATOR);
}
protected function addDebugListener(AbstractSync $sync, $resource)
{
$sync->getEventDispatcher()->addListener(UploadSync::BEFORE_TRANSFER, function (Event $e) use ($resource) {
$c = $e['command'];
if ($c instanceof CommandInterface) {
$uri = $c['Body']->getUri();
$size = $c['Body']->getSize();
fwrite($resource, "Uploading {$uri} -> {$c['Key']} ({$size} bytes)\n");
return;
}
// Multipart upload
$body = $c->getSource();
$totalSize = $body->getSize();
$progress = 0;
fwrite($resource, "Beginning multipart upload: " . $body->getUri() . ' -> ');
fwrite($resource, $c->getState()->getFromId('Key') . " ({$totalSize} bytes)\n");
$c->getEventDispatcher()->addListener(
AbstractTransfer::BEFORE_PART_UPLOAD,
function ($e) use (&$progress, $totalSize, $resource) {
$command = $e['command'];
$size = $command['Body']->getContentLength();
$percentage = number_format(($progress / $totalSize) * 100, 2);
fwrite($resource, "- Part {$command['PartNumber']} ({$size} bytes, {$percentage}%)\n");
$progress += $size;
}
);
});
}
}