Source of file S3Bucket.php
Size: 4,377 Bytes - Last Modified: 2021-12-24T06:46:39+00:00
/var/www/docs.ssmods.com/process/src/code/S3Bucket.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 | <?php /** * Bucket/container driver for Amazon S3 * Based on markguinn/silverstripe-cloudassets-rackspace * * @author Ed Linklater <ss@ed.geek.nz> * @package cloudassets * @subpackage buckets */ use Aws\Common\Aws; use Aws\Common\Enum\Size; use Aws\Common\Exception\MultipartUploadException; use Aws\S3\S3Client; use Aws\S3\Model\MultipartUpload\UploadBuilder; class S3Bucket extends CloudBucket { const CONTAINER = 'Container'; const REGION = 'Region'; const API_KEY = 'ApiKey'; const API_SECRET = 'ApiSecret'; const FORCE_DL = 'ForceDownload'; protected $client; /** * @param string $path * @param array $cfg * @throws Exception */ public function __construct($path, array $cfg=array()) { parent::__construct($path, $cfg); if (empty($cfg[self::CONTAINER])) throw new Exception('S3Bucket: missing configuration key - ' . self::CONTAINER); if (empty($cfg[self::REGION])) throw new Exception('S3Bucket: missing configuration key - ' . self::REGION); if (empty($cfg[self::API_KEY])) throw new Exception('S3Bucket: missing configuration key - ' . self::API_KEY); if (empty($cfg[self::API_SECRET])) throw new Exception('S3Bucket: missing configuration key - ' . self::API_SECRET); $this->containerName = $this->config[self::CONTAINER]; $this->client = S3Client::factory(array( 'key' => $this->config[self::API_KEY], 'secret' => $this->config[self::API_SECRET], 'region' => $this->config[self::REGION] )); } /** * @param File $f * @throws Exception */ public function put(File $f) { $fp = fopen($f->getFullPath(), 'r'); if (!$fp) throw new Exception('Unable to open file: ' . $f->getFilename()); $uploader = UploadBuilder::newInstance() ->setClient($this->client) ->setSource($f->getFullPath()) ->setBucket($this->containerName) ->setKey($this->getRelativeLinkFor($f)) ->build(); try { $uploader->upload(); } catch (MultipartUploadException $e) { $uploader->abort(); } } /** * @param File|string $f */ public function delete($f) { $this->client->deleteObject(array( 'Bucket' => $this->containerName, 'Key' => $this->getRelativeLinkFor($f), )); } /** * @param File $f * @param string $beforeName - contents of the Filename property (i.e. relative to site root) * @param string $afterName - contents of the Filename property (i.e. relative to site root) */ public function rename(File $f, $beforeName, $afterName) { $obj = $this->getFileObjectFor($beforeName); $result = $this->client->copyObject(array( 'Bucket' => $this->containerName, 'CopySource' => urlencode($this->containerName . '/' . $this->getRelativeLinkFor($beforeName)), 'Key' => $this->getRelativeLinkFor($afterName), )); if($result) $this->client->deleteObject(array( 'Bucket' => $this->containerName, 'Key' => $this->getRelativeLinkFor($beforeName), )); } /** * @param File $f * @return string */ public function getContents(File $f) { $obj = $this->getFileObjectFor($f); return $obj['Body']; } /** * This version just returns a normal link. I'm assuming most * buckets will implement this but I want it to be optional. * NOTE: I'm not sure how reliably this is working. * * @param File|string $f * @param int $expires [optional] - Expiration time in seconds * @return string */ public function getTemporaryLinkFor($f, $expires=3600) { $obj = $this->getFileObjectFor($this->getRelativeLinkFor($f)); return $obj['Body']->getUri(); } /** * @param $f - File object or filename * @return bool */ public function checkExists(File $f) { return $this->client->doesObjectExist( $this->containerName, $this->getRelativeLinkFor($f) ); } /** * @param $f - File object or filename * @return int - if file doesn't exist, returns -1 */ public function getFileSize(File $f) { if($obj = $this->getFileObjectFor($f)) { return $obj['ContentLength']; } else { return -1; } } /** * @param File|string $f * @return \Guzzle\Http\EntityBody */ protected function getFileObjectFor(File $f) { try { $result = $this->client->getObject(array( 'Bucket' => $this->containerName, 'Key' => $this->getRelativeLinkFor($f) )); return $result; } catch (\Aws\S3\Exception\NoSuchKeyException $e) { return -1; } } } |