File indexing completed on 2024-11-24 05:19:04
0001 <?php 0002 /** 0003 * file server - part of Opendesktop.org platform project <https://www.opendesktop.org>. 0004 * 0005 * Copyright (c) 2016 pling GmbH. 0006 * 0007 * This program is free software: you can redistribute it and/or modify 0008 * it under the terms of the GNU Affero General Public License as 0009 * published by the Free Software Foundation, either version 3 of the 0010 * License, or (at your option) any later version. 0011 * 0012 * This program is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0015 * GNU Affero General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU Affero General Public License 0018 * along with this program. If not, see <https://www.gnu.org/licenses/>. 0019 */ 0020 0021 namespace Ocs\Storage; 0022 0023 use Aws\Credentials\Credentials; 0024 use Aws\S3\S3Client; 0025 use finfo; 0026 0027 class S3Adapter implements AdapterInterface 0028 { 0029 private object $appConfig; 0030 private S3Client $s3Client; 0031 0032 public function __construct(object $appConfig) 0033 { 0034 $this->appConfig = $appConfig; 0035 } 0036 0037 /** 0038 * @inheritDoc 0039 */ 0040 public function moveUploadedFile(string $from, string $to): bool 0041 { 0042 error_log("from=$from, to=$to"); 0043 $finfo = new finfo(FILEINFO_MIME_TYPE); 0044 $type = $finfo->file($from); 0045 $md5sum = md5_file($from); 0046 0047 $bucketKey = $this->getBucketKey($to); 0048 0049 $awsClient = $this->getAwsClient(); 0050 $awsResult = $awsClient->putObject(['Bucket' => $this->appConfig->awss3['bucket'], 0051 'Key' => $bucketKey, 0052 'SourceFile' => $from, 0053 'ACL' => 'private', 0054 'ContentType' => $type,// 'ContentMD5' => base64_encode($md5sum), 0055 ]); 0056 0057 if (is_object($awsResult)) { 0058 if ($awsResult->get('@metadata')['statusCode'] != 200) { 0059 error_log(print_r($awsResult, true)); 0060 0061 return false; 0062 } 0063 if (trim($awsResult->get('ETag'), '"') != $md5sum) { 0064 error_log(__METHOD__ . ' - upload failure: checksum different'); 0065 error_log(print_r($awsResult, true)); 0066 0067 return false; 0068 } 0069 } 0070 error_log(print_r($awsResult, true)); 0071 0072 return true; 0073 } 0074 0075 /** 0076 * @param string $to 0077 * 0078 * @return string 0079 */ 0080 public function getBucketKey(string $to): string 0081 { 0082 $bucketPathPrefix = $this->appConfig->awss3['bucketPathPrefix']; 0083 $pos = strpos($to, $bucketPathPrefix); 0084 0085 return ltrim(substr($to, $pos), " /"); 0086 } 0087 0088 private function getAwsClient(): S3Client 0089 { 0090 if (!empty($this->s3Client)) { 0091 return $this->s3Client; 0092 } 0093 // Instantiate an Amazon S3 client. 0094 if (empty($this->appConfig->awss3['endpoint'])) { 0095 $this->s3Client = new S3Client(['credentials' => new Credentials($this->appConfig->awss3['key'], $this->appConfig->awss3['secret']), 0096 'version' => 'latest', 0097 'region' => $this->appConfig->awss3['region'],]); 0098 } else { 0099 $this->s3Client = new S3Client(['credentials' => new Credentials($this->appConfig->awss3['key'], $this->appConfig->awss3['secret']), 0100 'version' => 'latest', 0101 'region' => $this->appConfig->awss3['region'], 0102 'endpoint' => $this->appConfig->awss3['endpoint'],]); 0103 } 0104 0105 return $this->s3Client; 0106 } 0107 0108 public function fixFilename(string $name, string $collectionPath): string 0109 { 0110 $awsClient = $this->getAwsClient(); 0111 $counter = 0; 0112 while ($counter < 5) { 0113 $bucketName = $this->appConfig->awss3['bucketPathPrefix'] . '/' . $collectionPath . '/' . $name; 0114 $awsObjectExists = $awsClient->doesObjectExist($this->appConfig->awss3['bucket'], $bucketName); 0115 if (!$awsObjectExists) { 0116 break; 0117 } 0118 $counter++; 0119 $fix = date('YmdHis'); 0120 if (preg_match("/^([^.]+)(\..+)/", $name, $matches)) { 0121 $name = $matches[1] . '-' . $fix . $matches[2]; 0122 } else { 0123 $name = $name . '-' . $fix; 0124 } 0125 } 0126 0127 return $name; 0128 } 0129 0130 public function prepareCollectionPath(string $collectionName, string $filePath): bool 0131 { 0132 return true; 0133 } 0134 0135 public function testAndCreate(string $dir): bool 0136 { 0137 return true; 0138 } 0139 0140 public function moveFile($from, $to): bool 0141 { 0142 $awsClient = $this->getAwsClient(); 0143 $destKey = $this->getBucketKey($to); 0144 $srcKey = $this->getBucketKey($from); 0145 // $awsResult = $awsClient->headObject([ 0146 // 'Bucket' => $this->appConfig->awss3['bucket'], 0147 // 'Key' => $srcKey, 0148 // ]); 0149 $awsResult = $awsClient->copyObject(['Bucket' => $this->appConfig->awss3['bucket'], 0150 'Key' => $destKey, 0151 'CopySource' => $this->appConfig->awss3['bucket'] . '/' . $srcKey,]); 0152 error_log(__METHOD__ . ' - ' . 'copyObject: ' . print_r($awsResult, true)); 0153 if (is_object($awsResult)) { 0154 $responseCode = $awsResult->get('@metadata')['statusCode']; 0155 if (false == in_array($responseCode, [200, 201, 202, 204])) { 0156 error_log(print_r($awsResult, true)); 0157 0158 return false; 0159 } 0160 } 0161 0162 $awsResult = $awsClient->deleteObject(['Bucket' => $this->appConfig->awss3['bucket'], 0163 'Key' => $srcKey,]); 0164 error_log(__METHOD__ . ' - ' . 'copyObject: ' . print_r($awsResult, true)); 0165 0166 return true; 0167 } 0168 0169 public function copyFile($from, $to): bool 0170 { 0171 $awsClient = $this->getAwsClient(); 0172 $destKey = $this->getBucketKey($to); 0173 $srcKey = $this->getBucketKey($from); 0174 $awsResult = $awsClient->copyObject(['Bucket' => $this->appConfig->awss3['bucket'], 0175 'Key' => $destKey, 0176 'CopySource' => $this->appConfig->awss3['bucket'] . '/' . $srcKey,]); 0177 error_log(__METHOD__ . ' - ' . 'copyObject: ' . print_r($awsResult, true)); 0178 if (is_object($awsResult)) { 0179 $responseCode = $awsResult->get('@metadata')['statusCode']; 0180 if (false == in_array($responseCode, [200, 201, 202, 204])) { 0181 error_log(print_r($awsResult, true)); 0182 0183 return false; 0184 } 0185 } 0186 error_log(__METHOD__ . ' - ' . 'copyObject: ' . print_r($awsResult, true)); 0187 0188 return true; 0189 } 0190 0191 public function isFile($from): bool 0192 { 0193 $bucketName = $this->appConfig->awss3['bucketPathPrefix'] . '/' . $from; 0194 $awsClient = $this->getAwsClient(); 0195 0196 return $awsClient->doesObjectExist($this->appConfig->awss3['bucket'], $bucketName); 0197 } 0198 0199 }