1 <?php
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
17
18 namespace OpenCloud\ObjectStore;
19
20 use Guzzle\Http\EntityBody;
21 use OpenCloud\Common\Constants\Header;
22 use OpenCloud\Common\Constants\Mime;
23 use OpenCloud\Common\Exceptions;
24 use OpenCloud\Common\Exceptions\InvalidArgumentError;
25 use OpenCloud\Common\Http\Client;
26 use OpenCloud\Common\Http\Message\Formatter;
27 use OpenCloud\Common\Log\Logger;
28 use OpenCloud\Common\Service\ServiceBuilder;
29 use OpenCloud\ObjectStore\Constants\UrlType;
30 use OpenCloud\ObjectStore\Resource\Container;
31 use OpenCloud\ObjectStore\Upload\ContainerMigration;
32
33 34 35
36 class Service extends AbstractService
37 {
38 const DEFAULT_NAME = 'cloudFiles';
39 const DEFAULT_TYPE = 'object-store';
40 const BATCH_DELETE_MAX = 10000;
41
42 43 44 45 46
47 private $cdnService;
48
49 public function __construct(Client $client, $type = null, $name = null, $region = null, $urlType = null)
50 {
51 parent::__construct($client, $type, $name, $region, $urlType);
52
53 try {
54 $this->cdnService = ServiceBuilder::factory($client, 'OpenCloud\ObjectStore\CDNService', array(
55 'region' => $region
56 ));
57 } catch (Exceptions\EndpointError $e) {
58 }
59 }
60
61 62 63
64 public function getCdnService()
65 {
66 return $this->cdnService;
67 }
68
69 70 71 72 73 74
75 public function listContainers(array $filter = array())
76 {
77 $filter['format'] = 'json';
78 return $this->resourceList('Container', $this->getUrl(null, $filter), $this);
79 }
80
81 82 83 84
85 public function getContainer($data = null)
86 {
87 return new Container($this, $data);
88 }
89
90 91 92 93 94 95 96
97 public function createContainer($name, array $metadata = array())
98 {
99 $this->checkContainerName($name);
100
101 $containerHeaders = Container::stockHeaders($metadata);
102
103 $response = $this->getClient()
104 ->put($this->getUrl($name), $containerHeaders)
105 ->send();
106
107 if ($response->getStatusCode() == 201) {
108 return Container::fromResponse($response, $this);
109 }
110
111 return false;
112 }
113
114 115 116 117 118 119 120
121 public function checkContainerName($name)
122 {
123 if (strlen($name) == 0) {
124 $error = 'Container name cannot be blank';
125 }
126
127 if (strpos($name, '/') !== false) {
128 $error = 'Container name cannot contain "/"';
129 }
130
131 if (strlen($name) > self::MAX_CONTAINER_NAME_LENGTH) {
132 $error = 'Container name is too long';
133 }
134
135 if (isset($error)) {
136 throw new InvalidArgumentError($error);
137 }
138
139 return true;
140 }
141
142 143 144 145 146 147 148 149 150 151 152 153 154
155 public function bulkExtract($path = '', $archive, $archiveType = UrlType::TAR_GZ)
156 {
157 $entity = EntityBody::factory($archive);
158
159 $acceptableTypes = array(
160 UrlType::TAR,
161 UrlType::TAR_GZ,
162 UrlType::TAR_BZ2
163 );
164
165 if (!in_array($archiveType, $acceptableTypes)) {
166 throw new InvalidArgumentError(sprintf(
167 'The archive type must be one of the following: [%s]. You provided [%s].',
168 implode($acceptableTypes, ','),
169 print_r($archiveType, true)
170 ));
171 }
172
173 $url = $this->getUrl()->addPath($path)->setQuery(array('extract-archive' => $archiveType));
174 $response = $this->getClient()->put($url, array(Header::CONTENT_TYPE => ''), $entity)->send();
175
176 $body = Formatter::decode($response);
177
178 if (!empty($body->Errors)) {
179 throw new Exception\BulkOperationException((array) $body->Errors);
180 }
181
182 return $response;
183 }
184
185 186 187
188 public function bulkDelete(array $paths)
189 {
190 $this->getLogger()->warning(Logger::deprecated(__METHOD__, '::batchDelete()'));
191
192 return $this->executeBatchDeleteRequest($paths);
193 }
194
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
214 public function batchDelete(array $paths)
215 {
216 $chunks = array_chunk($paths, self::BATCH_DELETE_MAX);
217
218 $responses = array();
219
220 foreach ($chunks as $chunk) {
221 $responses[] = $this->executeBatchDeleteRequest($chunk);
222 }
223
224 return $responses;
225 }
226
227 228 229 230 231 232 233
234 private function executeBatchDeleteRequest(array $paths)
235 {
236 $entity = EntityBody::factory(implode(PHP_EOL, $paths));
237
238 $url = $this->getUrl()->setQuery(array('bulk-delete' => true));
239
240 $response = $this->getClient()
241 ->delete($url, array(Header::CONTENT_TYPE => Mime::TEXT), $entity)
242 ->send();
243
244 try {
245 $body = Formatter::decode($response);
246 if (!empty($body->Errors)) {
247 throw new Exception\BulkOperationException((array) $body->Errors);
248 }
249 } catch (Exceptions\JsonError $e) {
250 }
251
252 return $response;
253 }
254
255 256 257 258 259 260 261
262 public function migrateContainer(Container $old, Container $new, array $options = array())
263 {
264 $migration = ContainerMigration::factory($old, $new, $options);
265
266 return $migration->transfer();
267 }
268 }
269