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
2declare(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 */
24class 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