| Code Coverage
| Lines | Functions and Methods | Classes and Traits
Total | 0.00% covered (danger) | 0.00% | 0 / 215 | 0.00% covered (danger) | 0.00% | 0 / 28 | CRAP | 0.00% covered (danger) | 0.00% | 0 / 1
SeedDMS_Core_Storage_S3 | 0.00% covered (danger) | 0.00% | 0 / 215 | 0.00% covered (danger) | 0.00% | 0 / 28 | 2550 | 0.00% covered (danger) | 0.00% | 0 / 1
__construct | 0.00% covered (danger) | 0.00% | 0 / 4 | 0.00% covered (danger) | 0.00% | 0 / 1 | 2 |
getDocDir | 0.00% covered (danger) | 0.00% | 0 / 1 | 0.00% covered (danger) | 0.00% | 0 / 1 | 2 |
deleteContentDir | 0.00% covered (danger) | 0.00% | 0 / 9 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
deleteDocDir | 0.00% covered (danger) | 0.00% | 0 / 11 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
saveAttachment | 0.00% covered (danger) | 0.00% | 0 / 10 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
deleteAttachment | 0.00% covered (danger) | 0.00% | 0 / 9 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
getAttachment | 0.00% covered (danger) | 0.00% | 0 / 9 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
getAttachmentName | 0.00% covered (danger) | 0.00% | 0 / 3 | 0.00% covered (danger) | 0.00% | 0 / 1 | 2 |
getAttachmentFilesize | 0.00% covered (danger) | 0.00% | 0 / 6 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
getAttachmentMimeType | 0.00% covered (danger) | 0.00% | 0 / 6 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
saveContent | 0.00% covered (danger) | 0.00% | 0 / 11 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
setFileType | 0.00% covered (danger) | 0.00% | 0 / 15 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
replaceContent | 0.00% covered (danger) | 0.00% | 0 / 11 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
deleteContent | 0.00% covered (danger) | 0.00% | 0 / 10 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
getContent | 0.00% covered (danger) | 0.00% | 0 / 10 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
getContentName | 0.00% covered (danger) | 0.00% | 0 / 4 | 0.00% covered (danger) | 0.00% | 0 / 1 | 2 |
getContentStream | 0.00% covered (danger) | 0.00% | 0 / 11 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
getContentFilesize | 0.00% covered (danger) | 0.00% | 0 / 7 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
getContentMimetype | 0.00% covered (danger) | 0.00% | 0 / 7 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
getContentChecksum | 0.00% covered (danger) | 0.00% | 0 / 7 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
saveReview | 0.00% covered (danger) | 0.00% | 0 / 9 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
deleteReview | 0.00% covered (danger) | 0.00% | 0 / 8 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
getReview | 0.00% covered (danger) | 0.00% | 0 / 8 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
getReviewName | 0.00% covered (danger) | 0.00% | 0 / 2 | 0.00% covered (danger) | 0.00% | 0 / 1 | 2 |
saveApproval | 0.00% covered (danger) | 0.00% | 0 / 9 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
deleteApproval | 0.00% covered (danger) | 0.00% | 0 / 8 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
getApproval | 0.00% covered (danger) | 0.00% | 0 / 8 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 |
getApprovalName | 0.00% covered (danger) | 0.00% | 0 / 2 | 0.00% covered (danger) | 0.00% | 0 / 1 | 2 |

1 | <?php
2 | declare(strict_types=1);
3 |
4 | /**
5 | * Implementation of document storage
6 | *
7 | * @category DMS
8 | * @package SeedDMS_Core
9 | * @license GPL 2
10 | * @author Uwe Steinmann <uwe@steinmann.cx>
11 | * @copyright Copyright (C) 2010-2024 Uwe Steinmann
12 | */
13 |
14 | /**
15 | * Class with operations to put documents into the storage
16 | *
17 | * Use the methods to access the document storage
18 | *
19 | * @category DMS
20 | * @package SeedDMS_Core
21 | * @author Uwe Steinmann <uwe@steinmann.cx>
22 | * @copyright Copyright (C) 2010-2024 Uwe Steinmann
23 | */
24 | class SeedDMS_Core_Storage_S3 implements SeedDMS_Core_Storage {
25 |
26 | protected $basedir;
27 |
28 | protected $bucket;
29 |
30 | protected $s3client;
31 |
32 | public function __construct($bucket, $client) { /* {{{ */
33 | $this->bucket = $bucket;
34 | $this->basedir = '';
35 | $this->s3client = $client;
36 | $this->s3client->registerStreamWrapper();
37 | } /* }}} */
38 |
39 | protected function getDocDir($document) {
40 | return $document->getId().'-';
41 | }
42 |
43 | public function deleteContentDir() {
44 | $objects = $this->s3client->getIterator('ListObjects', array(
45 | 'Bucket' => $this->bucket,
46 | ));
47 | foreach ($objects as $object) {
48 | // print_r($object['Key'])."\n";
49 | $this->s3client->deleteObject([
50 | 'Bucket' => $this->bucket,
51 | 'Key' => $object['Key'],
52 | ]);
53 | }
54 | return true;
55 | }
56 |
57 | public function deleteDocDir($document) {
58 | $dir = $this->basedir . $this->getDocDir($document);
59 |
60 | $objects = $this->s3client->getIterator('ListObjects', array(
61 | 'Bucket' => $this->bucket,
62 | 'Prefix' => $dir,
63 | ));
64 | foreach ($objects as $object) {
65 | // print_r($object['Key'])."\n";
66 | $this->s3client->deleteObject([
67 | 'Bucket' => $this->bucket,
68 | 'Key' => $object['Key'],
69 | ]);
70 | }
71 | return true;
72 | }
73 |
74 | public function saveAttachment($document, $attachment, $tmpFile) {
75 | $dir = $this->basedir . $this->getDocDir($document);
76 | $fileType = $attachment->getFileType();
77 |
78 | try {
79 | $result = $this->s3client->putObject([
80 | 'Bucket' => $this->bucket,
81 | 'Key' => $dir.'f'.$attachment->getId().$fileType,
82 | 'SourceFile' => $tmpFile,
83 | ]);
84 | } catch (S3Exception $e) {
85 | return false;
86 | }
87 |
88 | return true;
89 | }
90 |
91 | public function deleteAttachment($document, $attachment) {
92 | $dir = $this->basedir . $this->getDocDir($document);
93 | $fileType = $attachment->getFileType();
94 |
95 | try {
96 | $result = $this->s3client->deleteObject([
97 | 'Bucket' => $this->bucket,
98 | 'Key' => $dir.'f'.$attachment->getId().$fileType,
99 | ]);
100 | } catch (S3Exception $e) {
101 | return false;
102 | }
103 |
104 | return true;
105 | }
106 |
107 | public function getAttachment($document, $attachment) {
108 | $dir = $this->basedir . $this->getDocDir($document);
109 | $fileType = $attachment->getFileType();
110 |
111 | try {
112 | $result = $this->s3client->getObject([
113 | 'Bucket' => $this->bucket,
114 | 'Key' => $dir.'f'.$attachment->getId().$fileType,
115 | ]);
116 | return $result['Body']->getContents();
117 | } catch (S3Exception $e) {
118 | return false;
119 | }
120 | }
121 |
122 | public function getAttachmentName($document, $attachment) {
123 | $dir = $this->basedir . $this->getDocDir($document);
124 | $filetype = $attachment->getFileType();
125 | return 's3//:'.$this->bucket.'/'.dir.'f'.$filetype;
126 | }
127 |
128 | public function getAttachmentFilesize($document, $attachment) {
129 | $dir = $this->basedir . $this->getDocDir($document);
130 | $fileType = $attachment->getFileType();
131 |
132 | try {
133 | $objInfo = $this->s3client->headObject(['Bucket'=>$this->bucket, 'Key'=>$dir.'f'.$attachment->getId().$filetype]);
134 | return $objInfo['ContentLength'];
135 | } catch (S3Exception $e) {
136 | return false;
137 | }
138 | }
139 |
140 | public function getAttachmentMimeType($document, $attachment) {
141 | $dir = $this->basedir . $this->getDocDir($document);
142 | $fileType = $attachment->getFileType();
143 |
144 | try {
145 | $objInfo = $this->s3client->headObject(['Bucket'=>$this->bucket, 'Key'=>$dir.'f'.$attachment->getId().$filetype]);
146 | return $objInfo['ContentType'];
147 | } catch (S3Exception $e) {
148 | return false;
149 | }
150 | }
151 |
152 | public function saveContent($document, $content, $tmpFile) {
153 | $dir = $this->basedir . $this->getDocDir($document);
154 | $version = $content->getVersion();
155 | $fileType = $content->getFileType();
156 |
157 | try {
158 | $result = $this->s3client->putObject([
159 | 'Bucket' => $this->bucket,
160 | 'Key' => $dir.$version.$fileType,
161 | 'SourceFile' => $tmpFile,
162 | ]);
163 | } catch (S3Exception $e) {
164 | return false;
165 | }
166 |
167 | return true;
168 | }
169 |
170 | public function setFileType($document, $content, $newfiletype) {
171 | $dir = $this->basedir . $this->getDocDir($document);
172 | $version = $content->getVersion();
173 | $filetype = $content->getFileType();
174 |
175 | try {
176 | $this->s3client->copyObject([
177 | 'Bucket' => $this->bucket,
178 | 'Key' => $dir.$version.$newfiletype,
179 | 'CopySource' => $this->bucket.'/'.$dir.$version.$filetype,
180 | ]);
181 | $this->s3client->deleteObject([
182 | 'Bucket' => $this->bucket,
183 | 'Key' => $dir.$version.$filetype,
184 | ]);
185 | return true;
186 | } catch (S3Exception $e) {
187 | return false;
188 | }
189 | }
190 |
191 | public function replaceContent($document, $content, $tmpFile) {
192 | $dir = $this->basedir . $this->getDocDir($document);
193 | $version = $content->getVersion();
194 | $fileType = $content->getFileType();
195 |
196 | try {
197 | $result = $this->s3client->putObject([
198 | 'Bucket' => $this->bucket,
199 | 'Key' => $dir.$version.$fileType,
200 | 'SourceFile' => $tmpFile,
201 | ]);
202 | return true;
203 | } catch (S3Exception $e) {
204 | return false;
205 | }
206 | }
207 |
208 | public function deleteContent($document, $content) {
209 | $dir = $this->basedir . $this->getDocDir($document);
210 | $version = $content->getVersion();
211 | $filetype = $content->getFileType();
212 |
213 | try {
214 | $result = $this->s3client->deleteObject([
215 | 'Bucket' => $this->bucket,
216 | 'Key' => $dir.$version.$filetype,
217 | ]);
218 | return true;
219 | } catch (S3Exception $e) {
220 | return false;
221 | }
222 | }
223 |
224 | public function getContent($document, $content) {
225 | $dir = $this->basedir . $this->getDocDir($document);
226 | $version = $content->getVersion();
227 | $filetype = $content->getFileType();
228 |
229 | try {
230 | $result = $this->s3client->getObject([
231 | 'Bucket' => $this->bucket,
232 | 'Key' => $dir.$version.$filetype,
233 | ]);
234 | return $result['Body']->getContents();
235 | } catch (S3Exception $e) {
236 | return false;
237 | }
238 | }
239 |
240 | public function getContentName($document, $content) {
241 | $dir = $this->basedir . $this->getDocDir($document);
242 | $version = $content->getVersion();
243 | $filetype = $content->getFileType();
244 | return 's3//:'.$this->bucket.'/'.dir.$version.$filetype;
245 | }
246 |
247 | public function getContentStream($document, $content) {
248 | $dir = $this->basedir . $this->getDocDir($document);
249 | $version = $content->getVersion();
250 | $filetype = $content->getFileType();
251 |
252 | try {
253 | $result = $this->s3client->getObject([
254 | 'Bucket' => $this->bucket,
255 | 'Key' => $dir.$version.$filetype,
256 | ]);
257 | $stream = new CachingStream($result['Body']);
258 | return $stream;
259 | } catch (S3Exception $e) {
260 | return false;
261 | }
262 | }
263 |
264 | public function getContentFilesize($document, $content) {
265 | $dir = $this->basedir . $this->getDocDir($document);
266 | $version = $content->getVersion();
267 | $filetype = $content->getFileType();
268 | try {
269 | $objInfo = $this->s3client->headObject(['Bucket'=>$this->bucket, 'Key'=>$dir.$version.$filetype]);
270 | return $objInfo['ContentLength'];
271 | } catch (S3Exception $e) {
272 | return false;
273 | }
274 | }
275 |
276 | public function getContentMimetype($document, $content) {
277 | $dir = $this->basedir . $this->getDocDir($document);
278 | $version = $content->getVersion();
279 | $filetype = $content->getFileType();
280 | try {
281 | $objInfo = $this->s3client->headObject(['Bucket'=>$this->bucket, 'Key'=>$dir.$version.$filetype]);
282 | return $objInfo['ContentType'];
283 | } catch (S3Exception $e) {
284 | return false;
285 | }
286 | }
287 |
288 | public function getContentChecksum($document, $content) {
289 | $dir = $this->basedir . $this->getDocDir($document);
290 | $version = $content->getVersion();
291 | $filetype = $content->getFileType();
292 | try {
293 | $objInfo = $this->s3client->headObject(['Bucket'=>$this->bucket, 'Key'=>$dir.$version.$filetype]);
294 | return substr($objInfo['ETag'], 1, -1);
295 | } catch (S3Exception $e) {
296 | return false;
297 | }
298 | }
299 |
300 | public function saveReview($document, $id, $tmpFile) {
301 | $dir = $this->basedir . $this->getDocDir($document);
302 |
303 | try {
304 | $result = $this->s3client->putObject([
305 | 'Bucket' => $this->bucket,
306 | 'Key' => $dir.'r'.$id,
307 | 'SourceFile' => $tmpFile,
308 | ]);
309 | } catch (S3Exception $e) {
310 | return false;
311 | }
312 |
313 | return true;
314 | }
315 |
316 | public function deleteReview($document, $id) {
317 | $dir = $this->basedir . $this->getDocDir($document);
318 |
319 | try {
320 | $result = $this->s3client->deleteObject([
321 | 'Bucket' => $this->bucket,
322 | 'Key' => $dir.'r'.$id,
323 | ]);
324 | } catch (S3Exception $e) {
325 | return false;
326 | }
327 |
328 | return true;
329 | }
330 |
331 | public function getReview($document, $id) {
332 | $dir = $this->basedir . $this->getDocDir($document);
333 |
334 | try {
335 | $result = $this->s3client->getObject([
336 | 'Bucket' => $this->bucket,
337 | 'Key' => $dir.'r'.$id,
338 | ]);
339 | return $result['Body']->getContents();
340 | } catch (S3Exception $e) {
341 | return false;
342 | }
343 |
344 | return true;
345 | }
346 |
347 | public function getReviewName($document, $id) {
348 | $dir = $this->basedir . $this->getDocDir($document);
349 | return 's3//:'.$this->bucket.'/'.dir.'r'.$id;
350 | }
351 |
352 | public function saveApproval($document, $id, $tmpFile) {
353 | $dir = $this->basedir . $this->getDocDir($document);
354 |
355 | try {
356 | $result = $this->s3client->putObject([
357 | 'Bucket' => $this->bucket,
358 | 'Key' => $dir.'a'.$id,
359 | 'SourceFile' => $tmpFile,
360 | ]);
361 | } catch (S3Exception $e) {
362 | return false;
363 | }
364 |
365 | return true;
366 | }
367 |
368 | public function deleteApproval($document, $id) {
369 | $dir = $this->basedir . $this->getDocDir($document);
370 |
371 | try {
372 | $result = $this->s3client->deleteObject([
373 | 'Bucket' => $this->bucket,
374 | 'Key' => $dir.'a'.$id,
375 | ]);
376 | } catch (S3Exception $e) {
377 | return false;
378 | }
379 |
380 | return true;
381 | }
382 |
383 | public function getApproval($document, $id) {
384 | $dir = $this->basedir . $this->getDocDir($document);
385 |
386 | try {
387 | $result = $this->s3client->getObject([
388 | 'Bucket' => $this->bucket,
389 | 'Key' => $dir.'a'.$id,
390 | ]);
391 | return $result['Body']->getContents();
392 | } catch (S3Exception $e) {
393 | return false;
394 | }
395 |
396 | return true;
397 | }
398 |
399 | public function getApprovalName($document, $id) {
400 | $dir = $this->basedir . $this->getDocDir($document);
401 | return 's3//:'.$this->bucket.'/'.dir.'a'.$id;
402 | }
403 |
404 | }
405 |