From e166ff56c61002eed4ef1629c1bcee412d3a5193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Bu=C3=9Fmann?= Date: Sat, 23 Jan 2016 18:48:22 +0100 Subject: [PATCH] Upgraded class to use with aws-sdk-php v3 (CloudFront functions missing) --- S3.php | 1269 +++++-------------------------------------- composer.json | 3 +- composer.lock | 530 ++++++++++++++++++ example-wrapper.php | 177 +----- 4 files changed, 687 insertions(+), 1292 deletions(-) create mode 100644 composer.lock diff --git a/S3.php b/S3.php index 660844c4..a50f1ea7 100644 --- a/S3.php +++ b/S3.php @@ -190,6 +190,15 @@ class S3 */ private static $__signingKeyResource = false; + /** + * Our aws client + * + * @var \Aws\S3\S3Client + * @access private + * @static + */ + private static $client = null; + /** * Constructor - if you're not using the class statically @@ -200,15 +209,20 @@ class S3 * @param string $endpoint Amazon URI * @return void */ - public function __construct($accessKey = null, $secretKey = null, $useSSL = false, $endpoint = 's3.amazonaws.com') + public function __construct($accessKey = null, $secretKey = null, $useSSL = false, $endpoint = 's3.amazonaws.com', $region = 'us-west-2') { if ($accessKey !== null && $secretKey !== null) - self::setAuth($accessKey, $secretKey); + { + self::$client = new \Aws\S3\S3Client(array( + 'credentials' => new \Aws\Credentials\Credentials($accessKey, $secretKey), + 'version' => '2006-03-01', + 'region' => $region + )); + } self::$useSSL = $useSSL; self::$endpoint = $endpoint; } - /** * Set the service endpoint * @@ -228,10 +242,19 @@ public function setEndpoint($host) * @param string $secretKey Secret key * @return void */ - public static function setAuth($accessKey, $secretKey) + public static function setAuth($accessKey, $secretKey, $region = 'us-west-2') { self::$__accessKey = $accessKey; self::$__secretKey = $secretKey; + if(!self::$client) + { + new S3($accessKey, $secretKey, false, 's3.amazonaws.com', $region); + } + } + + public static function registerStreamWrapper() + { + self::$client->registerStreamWrapper(); } @@ -314,15 +337,7 @@ public static function setExceptions($enabled = true) */ public static function setTimeCorrectionOffset($offset = 0) { - if ($offset == 0) - { - $rest = new S3Request('HEAD'); - $rest = $rest->getResponse(); - $awstime = $rest->headers['date']; - $systime = time(); - $offset = $systime > $awstime ? -($systime - $awstime) : ($awstime - $systime); - } - self::$__timeOffset = $offset; + // TODO: Implement setTimeCorrectionOffset() method. } @@ -383,33 +398,32 @@ private static function __triggerError($message, $file, $line, $code = 0) */ public static function listBuckets($detailed = false) { - $rest = new S3Request('GET', '', '', self::$endpoint); - $rest = $rest->getResponse(); - if ($rest->error === false && $rest->code !== 200) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) - { - self::__triggerError(sprintf("S3::listBuckets(): [%s] %s", $rest->error['code'], - $rest->error['message']), __FILE__, __LINE__); - return false; - } - $results = array(); - if (!isset($rest->body->Buckets)) return $results; + $buckets = self::$client->listBuckets()->toArray(); + $results = array(); if ($detailed) { - if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName)) - $results['owner'] = array( - 'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->DisplayName - ); + if (isset($buckets['Owner'], $buckets['Owner']['ID'], $buckets['Owner']['DisplayName'])) + { + $results['owner'] = array('id' => (string) $buckets['Owner']['ID'], + 'name' => (string) $buckets['Owner']['DisplayName'] + ); + } $results['buckets'] = array(); - foreach ($rest->body->Buckets->Bucket as $b) + foreach ($buckets['Buckets'] as $b) + { $results['buckets'][] = array( - 'name' => (string)$b->Name, 'time' => strtotime((string)$b->CreationDate) + 'name' => (string) $b['Name'], + 'time' => strtotime((string) $b['CreationDate']) ); + } } else - foreach ($rest->body->Buckets->Bucket as $b) $results[] = (string)$b->Name; - + { + foreach ($buckets['Buckets'] as $b) + { + $results[] = (string) $b['Name']; + } + } return $results; } @@ -429,81 +443,7 @@ public static function listBuckets($detailed = false) */ public static function getBucket($bucket, $prefix = null, $marker = null, $maxKeys = null, $delimiter = null, $returnCommonPrefixes = false) { - $rest = new S3Request('GET', $bucket, '', self::$endpoint); - if ($maxKeys == 0) $maxKeys = null; - if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix); - if ($marker !== null && $marker !== '') $rest->setParameter('marker', $marker); - if ($maxKeys !== null && $maxKeys !== '') $rest->setParameter('max-keys', $maxKeys); - if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter); - else if (!empty(self::$defDelimiter)) $rest->setParameter('delimiter', self::$defDelimiter); - $response = $rest->getResponse(); - if ($response->error === false && $response->code !== 200) - $response->error = array('code' => $response->code, 'message' => 'Unexpected HTTP status'); - if ($response->error !== false) - { - self::__triggerError(sprintf("S3::getBucket(): [%s] %s", - $response->error['code'], $response->error['message']), __FILE__, __LINE__); - return false; - } - - $results = array(); - - $nextMarker = null; - if (isset($response->body, $response->body->Contents)) - foreach ($response->body->Contents as $c) - { - $results[(string)$c->Key] = array( - 'name' => (string)$c->Key, - 'time' => strtotime((string)$c->LastModified), - 'size' => (int)$c->Size, - 'hash' => substr((string)$c->ETag, 1, -1) - ); - $nextMarker = (string)$c->Key; - } - - if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes)) - foreach ($response->body->CommonPrefixes as $c) - $results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix); - - if (isset($response->body, $response->body->IsTruncated) && - (string)$response->body->IsTruncated == 'false') return $results; - - if (isset($response->body, $response->body->NextMarker)) - $nextMarker = (string)$response->body->NextMarker; - - // Loop through truncated results if maxKeys isn't specified - if ($maxKeys == null && $nextMarker !== null && (string)$response->body->IsTruncated == 'true') - do - { - $rest = new S3Request('GET', $bucket, '', self::$endpoint); - if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix); - $rest->setParameter('marker', $nextMarker); - if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter); - - if (($response = $rest->getResponse()) == false || $response->code !== 200) break; - - if (isset($response->body, $response->body->Contents)) - foreach ($response->body->Contents as $c) - { - $results[(string)$c->Key] = array( - 'name' => (string)$c->Key, - 'time' => strtotime((string)$c->LastModified), - 'size' => (int)$c->Size, - 'hash' => substr((string)$c->ETag, 1, -1) - ); - $nextMarker = (string)$c->Key; - } - - if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes)) - foreach ($response->body->CommonPrefixes as $c) - $results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix); - - if (isset($response->body, $response->body->NextMarker)) - $nextMarker = (string)$response->body->NextMarker; - - } while ($response !== false && (string)$response->body->IsTruncated == 'true'); - - return $results; + // TODO: Implement getBucket() method. } @@ -511,37 +451,26 @@ public static function getBucket($bucket, $prefix = null, $marker = null, $maxKe * Put a bucket * * @param string $bucket Bucket name - * @param constant $acl ACL flag - * @param string $location Set as "EU" to create buckets hosted in Europe + * @param string $acl ACL flag + * @param string|bool $location Set as "EU" to create buckets hosted in Europe or specify location (i.e. cn-north-1) * @return boolean */ public static function putBucket($bucket, $acl = self::ACL_PRIVATE, $location = false) { - $rest = new S3Request('PUT', $bucket, '', self::$endpoint); - $rest->setAmzHeader('x-amz-acl', $acl); - - if ($location !== false) - { - $dom = new DOMDocument; - $createBucketConfiguration = $dom->createElement('CreateBucketConfiguration'); - $locationConstraint = $dom->createElement('LocationConstraint', $location); - $createBucketConfiguration->appendChild($locationConstraint); - $dom->appendChild($createBucketConfiguration); - $rest->data = $dom->saveXML(); - $rest->size = strlen($rest->data); - $rest->setHeader('Content-Type', 'application/xml'); + try + { + self::$client->createBucket(array( + 'Bucket' => $bucket, + 'ACL' => $acl, + 'LocationConstraint' => is_string($location) && strtolower($location) == 'eu' ? 'eu-west-1' : (is_string($location) ? $location : ($location ? 'eu-central-1' : 'us-west-1')) + )); + return true; } - $rest = $rest->getResponse(); - - if ($rest->error === false && $rest->code !== 200) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) + catch(Exception $ex) { - self::__triggerError(sprintf("S3::putBucket({$bucket}, {$acl}, {$location}): [%s] %s", - $rest->error['code'], $rest->error['message']), __FILE__, __LINE__); + self::__triggerError(sprintf("S3::putBucket({$bucket}, {$acl}, {$location}): [%s] %s", $ex->getCode(), $ex->getMessage()), __FILE__, __LINE__); return false; } - return true; } @@ -549,21 +478,20 @@ public static function putBucket($bucket, $acl = self::ACL_PRIVATE, $location = * Delete an empty bucket * * @param string $bucket Bucket name + * @param bool $force Force delete not empty folders? * @return boolean */ public static function deleteBucket($bucket) { - $rest = new S3Request('DELETE', $bucket, '', self::$endpoint); - $rest = $rest->getResponse(); - if ($rest->error === false && $rest->code !== 204) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) + try { - self::__triggerError(sprintf("S3::deleteBucket({$bucket}): [%s] %s", - $rest->error['code'], $rest->error['message']), __FILE__, __LINE__); + self::$client->deleteBucket(array('Bucket' => $bucket)); + } + catch(Exception $ex) + { + self::__triggerError(sprintf("S3::deleteBucket({$bucket}): [%s] %s", $ex->getCode(), $ex->getMessage()), __FILE__, __LINE__); return false; } - return true; } @@ -582,8 +510,7 @@ public static function inputFile($file, $md5sum = true) return false; } clearstatcache(false, $file); - return array('file' => $file, 'size' => filesize($file), 'md5sum' => $md5sum !== false ? - (is_string($md5sum) ? $md5sum : base64_encode(md5_file($file, true))) : ''); + return \Guzzle\Http\EntityBody::factory(fopen($file, 'r+')); } @@ -597,26 +524,7 @@ public static function inputFile($file, $md5sum = true) */ public static function inputResource(&$resource, $bufferSize = false, $md5sum = '') { - if (!is_resource($resource) || (int)$bufferSize < 0) - { - self::__triggerError('S3::inputResource(): Invalid resource or buffer size', __FILE__, __LINE__); - return false; - } - - // Try to figure out the bytesize - if ($bufferSize === false) - { - if (fseek($resource, 0, SEEK_END) < 0 || ($bufferSize = ftell($resource)) === false) - { - self::__triggerError('S3::inputResource(): Unable to obtain resource size', __FILE__, __LINE__); - return false; - } - fseek($resource, 0); - } - - $input = array('size' => $bufferSize, 'md5sum' => $md5sum); - $input['fp'] =& $resource; - return $input; + return $resource; } @@ -635,79 +543,23 @@ public static function inputResource(&$resource, $bufferSize = false, $md5sum = */ public static function putObject($input, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array(), $storageClass = self::STORAGE_CLASS_STANDARD, $serverSideEncryption = self::SSE_NONE) { - if ($input === false) return false; - $rest = new S3Request('PUT', $bucket, $uri, self::$endpoint); - - if (!is_array($input)) $input = array( - 'data' => $input, 'size' => strlen($input), - 'md5sum' => base64_encode(md5($input, true)) - ); - - // Data - if (isset($input['fp'])) - $rest->fp =& $input['fp']; - elseif (isset($input['file'])) - $rest->fp = @fopen($input['file'], 'rb'); - elseif (isset($input['data'])) - $rest->data = $input['data']; - - // Content-Length (required) - if (isset($input['size']) && $input['size'] >= 0) - $rest->size = $input['size']; - else { - if (isset($input['file'])) { - clearstatcache(false, $input['file']); - $rest->size = filesize($input['file']); - } - elseif (isset($input['data'])) - $rest->size = strlen($input['data']); + try + { + self::$client->putObject(array( + 'ACL' => $acl, + 'Bucket' => $bucket, + 'Key' => $uri, + 'Body' => $input, + 'StorageClass' => $storageClass, + 'ServerSideEncryption' => $serverSideEncryption + )); + return true; } - - // Custom request headers (Content-Type, Content-Disposition, Content-Encoding) - if (is_array($requestHeaders)) - foreach ($requestHeaders as $h => $v) - strpos($h, 'x-amz-') === 0 ? $rest->setAmzHeader($h, $v) : $rest->setHeader($h, $v); - elseif (is_string($requestHeaders)) // Support for legacy contentType parameter - $input['type'] = $requestHeaders; - - // Content-Type - if (!isset($input['type'])) - { - if (isset($requestHeaders['Content-Type'])) - $input['type'] =& $requestHeaders['Content-Type']; - elseif (isset($input['file'])) - $input['type'] = self::__getMIMEType($input['file']); - else - $input['type'] = 'application/octet-stream'; - } - - if ($storageClass !== self::STORAGE_CLASS_STANDARD) // Storage class - $rest->setAmzHeader('x-amz-storage-class', $storageClass); - - if ($serverSideEncryption !== self::SSE_NONE) // Server-side encryption - $rest->setAmzHeader('x-amz-server-side-encryption', $serverSideEncryption); - - // We need to post with Content-Length and Content-Type, MD5 is optional - if ($rest->size >= 0 && ($rest->fp !== false || $rest->data !== false)) - { - $rest->setHeader('Content-Type', $input['type']); - if (isset($input['md5sum'])) $rest->setHeader('Content-MD5', $input['md5sum']); - - $rest->setAmzHeader('x-amz-acl', $acl); - foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v); - $rest->getResponse(); - } else - $rest->response->error = array('code' => 0, 'message' => 'Missing input parameters'); - - if ($rest->response->error === false && $rest->response->code !== 200) - $rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status'); - if ($rest->response->error !== false) + catch(Exception $ex) { - self::__triggerError(sprintf("S3::putObject(): [%s] %s", - $rest->response->error['code'], $rest->response->error['message']), __FILE__, __LINE__); + self::__triggerError(sprintf("S3::putObject(): [%s] %s", $ex->getCode(), $ex->getMessage()), __FILE__, __LINE__); return false; } - return true; } @@ -755,28 +607,24 @@ public static function putObjectString($string, $bucket, $uri, $acl = self::ACL_ */ public static function getObject($bucket, $uri, $saveTo = false) { - $rest = new S3Request('GET', $bucket, $uri, self::$endpoint); - if ($saveTo !== false) + try { - if (is_resource($saveTo)) - $rest->fp =& $saveTo; - else - if (($rest->fp = @fopen($saveTo, 'wb')) !== false) - $rest->file = realpath($saveTo); - else - $rest->response->error = array('code' => 0, 'message' => 'Unable to open save file for writing: '.$saveTo); + $data = array( + 'Bucket' => $bucket, + 'Key' => $uri + ); + if($saveTo) + { + $data['SaveAs'] = $saveTo; + } + $result = self::$client->getObject($data); + return (string) $result['Body']; } - if ($rest->response->error === false) $rest->getResponse(); - - if ($rest->response->error === false && $rest->response->code !== 200) - $rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status'); - if ($rest->response->error !== false) + catch(Exception $ex) { - self::__triggerError(sprintf("S3::getObject({$bucket}, {$uri}): [%s] %s", - $rest->response->error['code'], $rest->response->error['message']), __FILE__, __LINE__); + self::__triggerError(sprintf("S3::getObject({$bucket}, {$uri}): [%s] %s", $ex->getCode(), $ex->getMessage()), __FILE__, __LINE__); return false; } - return $rest->response; } @@ -790,17 +638,7 @@ public static function getObject($bucket, $uri, $saveTo = false) */ public static function getObjectInfo($bucket, $uri, $returnInfo = true) { - $rest = new S3Request('HEAD', $bucket, $uri, self::$endpoint); - $rest = $rest->getResponse(); - if ($rest->error === false && ($rest->code !== 200 && $rest->code !== 404)) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) - { - self::__triggerError(sprintf("S3::getObjectInfo({$bucket}, {$uri}): [%s] %s", - $rest->error['code'], $rest->error['message']), __FILE__, __LINE__); - return false; - } - return $rest->code == 200 ? $returnInfo ? $rest->headers : true : false; + // TODO: Implement getObjectInfo() method. } @@ -819,31 +657,7 @@ public static function getObjectInfo($bucket, $uri, $returnInfo = true) */ public static function copyObject($srcBucket, $srcUri, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array(), $storageClass = self::STORAGE_CLASS_STANDARD) { - $rest = new S3Request('PUT', $bucket, $uri, self::$endpoint); - $rest->setHeader('Content-Length', 0); - foreach ($requestHeaders as $h => $v) - strpos($h, 'x-amz-') === 0 ? $rest->setAmzHeader($h, $v) : $rest->setHeader($h, $v); - foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v); - if ($storageClass !== self::STORAGE_CLASS_STANDARD) // Storage class - $rest->setAmzHeader('x-amz-storage-class', $storageClass); - $rest->setAmzHeader('x-amz-acl', $acl); - $rest->setAmzHeader('x-amz-copy-source', sprintf('/%s/%s', $srcBucket, rawurlencode($srcUri))); - if (sizeof($requestHeaders) > 0 || sizeof($metaHeaders) > 0) - $rest->setAmzHeader('x-amz-metadata-directive', 'REPLACE'); - - $rest = $rest->getResponse(); - if ($rest->error === false && $rest->code !== 200) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) - { - self::__triggerError(sprintf("S3::copyObject({$srcBucket}, {$srcUri}, {$bucket}, {$uri}): [%s] %s", - $rest->error['code'], $rest->error['message']), __FILE__, __LINE__); - return false; - } - return isset($rest->body->LastModified, $rest->body->ETag) ? array( - 'time' => strtotime((string)$rest->body->LastModified), - 'hash' => substr((string)$rest->body->ETag, 1, -1) - ) : false; + // TODO: Implement copyObject() method. } @@ -856,35 +670,7 @@ public static function copyObject($srcBucket, $srcUri, $bucket, $uri, $acl = sel */ public static function setBucketRedirect($bucket = NULL, $location = NULL) { - $rest = new S3Request('PUT', $bucket, '', self::$endpoint); - - if( empty($bucket) || empty($location) ) { - self::__triggerError("S3::setBucketRedirect({$bucket}, {$location}): Empty parameter.", __FILE__, __LINE__); - return false; - } - - $dom = new DOMDocument; - $websiteConfiguration = $dom->createElement('WebsiteConfiguration'); - $redirectAllRequestsTo = $dom->createElement('RedirectAllRequestsTo'); - $hostName = $dom->createElement('HostName', $location); - $redirectAllRequestsTo->appendChild($hostName); - $websiteConfiguration->appendChild($redirectAllRequestsTo); - $dom->appendChild($websiteConfiguration); - $rest->setParameter('website', null); - $rest->data = $dom->saveXML(); - $rest->size = strlen($rest->data); - $rest->setHeader('Content-Type', 'application/xml'); - $rest = $rest->getResponse(); - - if ($rest->error === false && $rest->code !== 200) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) - { - self::__triggerError(sprintf("S3::setBucketRedirect({$bucket}, {$location}): [%s] %s", - $rest->error['code'], $rest->error['message']), __FILE__, __LINE__); - return false; - } - return true; + // TODO: Implement setBucketRedirect() method. } @@ -898,56 +684,7 @@ public static function setBucketRedirect($bucket = NULL, $location = NULL) */ public static function setBucketLogging($bucket, $targetBucket, $targetPrefix = null) { - // The S3 log delivery group has to be added to the target bucket's ACP - if ($targetBucket !== null && ($acp = self::getAccessControlPolicy($targetBucket, '')) !== false) - { - // Only add permissions to the target bucket when they do not exist - $aclWriteSet = false; - $aclReadSet = false; - foreach ($acp['acl'] as $acl) - if ($acl['type'] == 'Group' && $acl['uri'] == 'http://acs.amazonaws.com/groups/s3/LogDelivery') - { - if ($acl['permission'] == 'WRITE') $aclWriteSet = true; - elseif ($acl['permission'] == 'READ_ACP') $aclReadSet = true; - } - if (!$aclWriteSet) $acp['acl'][] = array( - 'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'WRITE' - ); - if (!$aclReadSet) $acp['acl'][] = array( - 'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'READ_ACP' - ); - if (!$aclReadSet || !$aclWriteSet) self::setAccessControlPolicy($targetBucket, '', $acp); - } - - $dom = new DOMDocument; - $bucketLoggingStatus = $dom->createElement('BucketLoggingStatus'); - $bucketLoggingStatus->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); - if ($targetBucket !== null) - { - if ($targetPrefix == null) $targetPrefix = $bucket . '-'; - $loggingEnabled = $dom->createElement('LoggingEnabled'); - $loggingEnabled->appendChild($dom->createElement('TargetBucket', $targetBucket)); - $loggingEnabled->appendChild($dom->createElement('TargetPrefix', $targetPrefix)); - // TODO: Add TargetGrants? - $bucketLoggingStatus->appendChild($loggingEnabled); - } - $dom->appendChild($bucketLoggingStatus); - - $rest = new S3Request('PUT', $bucket, '', self::$endpoint); - $rest->setParameter('logging', null); - $rest->data = $dom->saveXML(); - $rest->size = strlen($rest->data); - $rest->setHeader('Content-Type', 'application/xml'); - $rest = $rest->getResponse(); - if ($rest->error === false && $rest->code !== 200) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) - { - self::__triggerError(sprintf("S3::setBucketLogging({$bucket}, {$targetBucket}): [%s] %s", - $rest->error['code'], $rest->error['message']), __FILE__, __LINE__); - return false; - } - return true; + // TODO: Implement setBucketLogging() method. } @@ -962,22 +699,7 @@ public static function setBucketLogging($bucket, $targetBucket, $targetPrefix = */ public static function getBucketLogging($bucket) { - $rest = new S3Request('GET', $bucket, '', self::$endpoint); - $rest->setParameter('logging', null); - $rest = $rest->getResponse(); - if ($rest->error === false && $rest->code !== 200) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) - { - self::__triggerError(sprintf("S3::getBucketLogging({$bucket}): [%s] %s", - $rest->error['code'], $rest->error['message']), __FILE__, __LINE__); - return false; - } - if (!isset($rest->body->LoggingEnabled)) return false; // No logging - return array( - 'targetBucket' => (string)$rest->body->LoggingEnabled->TargetBucket, - 'targetPrefix' => (string)$rest->body->LoggingEnabled->TargetPrefix, - ); + // TODO: Implement getBucketLogging() method. } @@ -1001,18 +723,7 @@ public static function disableBucketLogging($bucket) */ public static function getBucketLocation($bucket) { - $rest = new S3Request('GET', $bucket, '', self::$endpoint); - $rest->setParameter('location', null); - $rest = $rest->getResponse(); - if ($rest->error === false && $rest->code !== 200) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) - { - self::__triggerError(sprintf("S3::getBucketLocation({$bucket}): [%s] %s", - $rest->error['code'], $rest->error['message']), __FILE__, __LINE__); - return false; - } - return (isset($rest->body[0]) && (string)$rest->body[0] !== '') ? (string)$rest->body[0] : 'US'; + // TODO: Implement getBucketLocation() method. } @@ -1026,60 +737,7 @@ public static function getBucketLocation($bucket) */ public static function setAccessControlPolicy($bucket, $uri = '', $acp = array()) { - $dom = new DOMDocument; - $dom->formatOutput = true; - $accessControlPolicy = $dom->createElement('AccessControlPolicy'); - $accessControlList = $dom->createElement('AccessControlList'); - - // It seems the owner has to be passed along too - $owner = $dom->createElement('Owner'); - $owner->appendChild($dom->createElement('ID', $acp['owner']['id'])); - $owner->appendChild($dom->createElement('DisplayName', $acp['owner']['name'])); - $accessControlPolicy->appendChild($owner); - - foreach ($acp['acl'] as $g) - { - $grant = $dom->createElement('Grant'); - $grantee = $dom->createElement('Grantee'); - $grantee->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); - if (isset($g['id'])) - { // CanonicalUser (DisplayName is omitted) - $grantee->setAttribute('xsi:type', 'CanonicalUser'); - $grantee->appendChild($dom->createElement('ID', $g['id'])); - } - elseif (isset($g['email'])) - { // AmazonCustomerByEmail - $grantee->setAttribute('xsi:type', 'AmazonCustomerByEmail'); - $grantee->appendChild($dom->createElement('EmailAddress', $g['email'])); - } - elseif ($g['type'] == 'Group') - { // Group - $grantee->setAttribute('xsi:type', 'Group'); - $grantee->appendChild($dom->createElement('URI', $g['uri'])); - } - $grant->appendChild($grantee); - $grant->appendChild($dom->createElement('Permission', $g['permission'])); - $accessControlList->appendChild($grant); - } - - $accessControlPolicy->appendChild($accessControlList); - $dom->appendChild($accessControlPolicy); - - $rest = new S3Request('PUT', $bucket, $uri, self::$endpoint); - $rest->setParameter('acl', null); - $rest->data = $dom->saveXML(); - $rest->size = strlen($rest->data); - $rest->setHeader('Content-Type', 'application/xml'); - $rest = $rest->getResponse(); - if ($rest->error === false && $rest->code !== 200) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) - { - self::__triggerError(sprintf("S3::setAccessControlPolicy({$bucket}, {$uri}): [%s] %s", - $rest->error['code'], $rest->error['message']), __FILE__, __LINE__); - return false; - } - return true; + // TODO: Implement setAccessControlPolicy() method. } @@ -1092,55 +750,7 @@ public static function setAccessControlPolicy($bucket, $uri = '', $acp = array() */ public static function getAccessControlPolicy($bucket, $uri = '') { - $rest = new S3Request('GET', $bucket, $uri, self::$endpoint); - $rest->setParameter('acl', null); - $rest = $rest->getResponse(); - if ($rest->error === false && $rest->code !== 200) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) - { - self::__triggerError(sprintf("S3::getAccessControlPolicy({$bucket}, {$uri}): [%s] %s", - $rest->error['code'], $rest->error['message']), __FILE__, __LINE__); - return false; - } - - $acp = array(); - if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName)) - $acp['owner'] = array( - 'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->DisplayName - ); - - if (isset($rest->body->AccessControlList)) - { - $acp['acl'] = array(); - foreach ($rest->body->AccessControlList->Grant as $grant) - { - foreach ($grant->Grantee as $grantee) - { - if (isset($grantee->ID, $grantee->DisplayName)) // CanonicalUser - $acp['acl'][] = array( - 'type' => 'CanonicalUser', - 'id' => (string)$grantee->ID, - 'name' => (string)$grantee->DisplayName, - 'permission' => (string)$grant->Permission - ); - elseif (isset($grantee->EmailAddress)) // AmazonCustomerByEmail - $acp['acl'][] = array( - 'type' => 'AmazonCustomerByEmail', - 'email' => (string)$grantee->EmailAddress, - 'permission' => (string)$grant->Permission - ); - elseif (isset($grantee->URI)) // Group - $acp['acl'][] = array( - 'type' => 'Group', - 'uri' => (string)$grantee->URI, - 'permission' => (string)$grant->Permission - ); - else continue; - } - } - } - return $acp; + // TODO: Implement getAccessControlPolicy() method. } @@ -1153,17 +763,20 @@ public static function getAccessControlPolicy($bucket, $uri = '') */ public static function deleteObject($bucket, $uri) { - $rest = new S3Request('DELETE', $bucket, $uri, self::$endpoint); - $rest = $rest->getResponse(); - if ($rest->error === false && $rest->code !== 204) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) + try { - self::__triggerError(sprintf("S3::deleteObject(): [%s] %s", - $rest->error['code'], $rest->error['message']), __FILE__, __LINE__); + self::$client->deleteObject(array( + 'Bucket' => $bucket, + 'Key' => $uri + )); + + return true; + } + catch(Exception $ex) + { + self::__triggerError(sprintf("S3::deleteObject({$bucket}, {$uri}): [%s] %s", $ex->getCode(), $ex->getMessage()), __FILE__, __LINE__); return false; } - return true; } @@ -1175,16 +788,25 @@ public static function deleteObject($bucket, $uri) * @param integer $lifetime Lifetime in seconds * @param boolean $hostBucket Use the bucket name as the hostname * @param boolean $https Use HTTPS ($hostBucket should be false for SSL verification) - * @return string + * @return string|bool */ public static function getAuthenticatedURL($bucket, $uri, $lifetime, $hostBucket = false, $https = false) { - $expires = self::__getTime() + $lifetime; - $uri = str_replace(array('%2F', '%2B'), array('/', '+'), rawurlencode($uri)); - return sprintf(($https ? 'https' : 'http').'://%s/%s?AWSAccessKeyId=%s&Expires=%u&Signature=%s', - // $hostBucket ? $bucket : $bucket.'.s3.amazonaws.com', $uri, self::$__accessKey, $expires, - $hostBucket ? $bucket : self::$endpoint.'/'.$bucket, $uri, self::$__accessKey, $expires, - urlencode(self::__getHash("GET\n\n\n{$expires}\n/{$bucket}/{$uri}"))); + try + { + /** @var \Aws\Command $command */ + $command = self::$client->getCommand('PutObject', array( + 'Bucket' => $bucket, + 'Key' => $uri + )); + + return self::$client->createPresignedRequest($command, '+' . $lifetime . ' seconds'); + } + catch(Exception $ex) + { + self::__triggerError(sprintf("S3::getAuthenticatedURL({$bucket}, {$uri}, {$lifetime}, ...): [%s] %s", $ex->getCode(), $ex->getMessage()), __FILE__, __LINE__); + return false; + } } @@ -1196,17 +818,7 @@ public static function getAuthenticatedURL($bucket, $uri, $lifetime, $hostBucket */ public static function getSignedPolicyURL($policy) { - $data = json_encode($policy); - $signature = ''; - if (!openssl_sign($data, $signature, self::$__signingKeyResource)) return false; - - $encoded = str_replace(array('+', '='), array('-', '_', '~'), base64_encode($data)); - $signature = str_replace(array('+', '='), array('-', '_', '~'), base64_encode($signature)); - - $url = $policy['Statement'][0]['Resource'] . '?'; - foreach (array('Policy' => $encoded, 'Signature' => $signature, 'Key-Pair-Id' => self::$__signingKeyPairId) as $k => $v) - $url .= $k.'='.str_replace('%2F', '/', rawurlencode($v)).'&'; - return substr($url, 0, -1); + // TODO: Implement getSignedPolicyURL() method. } @@ -1219,13 +831,7 @@ public static function getSignedPolicyURL($policy) */ public static function getSignedCannedURL($url, $lifetime) { - return self::getSignedPolicyURL(array( - 'Statement' => array( - array('Resource' => $url, 'Condition' => array( - 'DateLessThan' => array('AWS:EpochTime' => self::__getTime() + $lifetime) - )) - ) - )); + // TODO: Implement getSignedCannedURL() method. } @@ -1246,50 +852,7 @@ public static function getSignedCannedURL($url, $lifetime) public static function getHttpUploadPostParams($bucket, $uriPrefix = '', $acl = self::ACL_PRIVATE, $lifetime = 3600, $maxFileSize = 5242880, $successRedirect = "201", $amzHeaders = array(), $headers = array(), $flashVars = false) { - // Create policy object - $policy = new stdClass; - $policy->expiration = gmdate('Y-m-d\TH:i:s\Z', (self::__getTime() + $lifetime)); - $policy->conditions = array(); - $obj = new stdClass; $obj->bucket = $bucket; array_push($policy->conditions, $obj); - $obj = new stdClass; $obj->acl = $acl; array_push($policy->conditions, $obj); - - $obj = new stdClass; // 200 for non-redirect uploads - if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201))) - $obj->success_action_status = (string)$successRedirect; - else // URL - $obj->success_action_redirect = $successRedirect; - array_push($policy->conditions, $obj); - - if ($acl !== self::ACL_PUBLIC_READ) - array_push($policy->conditions, array('eq', '$acl', $acl)); - - array_push($policy->conditions, array('starts-with', '$key', $uriPrefix)); - if ($flashVars) array_push($policy->conditions, array('starts-with', '$Filename', '')); - foreach (array_keys($headers) as $headerKey) - array_push($policy->conditions, array('starts-with', '$'.$headerKey, '')); - foreach ($amzHeaders as $headerKey => $headerVal) - { - $obj = new stdClass; - $obj->{$headerKey} = (string)$headerVal; - array_push($policy->conditions, $obj); - } - array_push($policy->conditions, array('content-length-range', 0, $maxFileSize)); - $policy = base64_encode(str_replace('\/', '/', json_encode($policy))); - - // Create parameters - $params = new stdClass; - $params->AWSAccessKeyId = self::$__accessKey; - $params->key = $uriPrefix.'${filename}'; - $params->acl = $acl; - $params->policy = $policy; unset($policy); - $params->signature = self::__getHash($params->policy); - if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201))) - $params->success_action_status = (string)$successRedirect; - else - $params->success_action_redirect = $successRedirect; - foreach ($headers as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal; - foreach ($amzHeaders as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal; - return $params; + // TODO: Implement getHttpUploadPostParams() method. } @@ -1307,43 +870,7 @@ public static function getHttpUploadPostParams($bucket, $uriPrefix = '', $acl = */ public static function createDistribution($bucket, $enabled = true, $cnames = array(), $comment = null, $defaultRootObject = null, $originAccessIdentity = null, $trustedSigners = array()) { - if (!extension_loaded('openssl')) - { - self::__triggerError(sprintf("S3::createDistribution({$bucket}, ".(int)$enabled.", [], '$comment'): %s", - "CloudFront functionality requires SSL"), __FILE__, __LINE__); - return false; - } - $useSSL = self::$useSSL; - - self::$useSSL = true; // CloudFront requires SSL - $rest = new S3Request('POST', '', '2010-11-01/distribution', 'cloudfront.amazonaws.com'); - $rest->data = self::__getCloudFrontDistributionConfigXML( - $bucket.'.s3.amazonaws.com', - $enabled, - (string)$comment, - (string)microtime(true), - $cnames, - $defaultRootObject, - $originAccessIdentity, - $trustedSigners - ); - - $rest->size = strlen($rest->data); - $rest->setHeader('Content-Type', 'application/xml'); - $rest = self::__getCloudFrontResponse($rest); - - self::$useSSL = $useSSL; - - if ($rest->error === false && $rest->code !== 201) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) - { - self::__triggerError(sprintf("S3::createDistribution({$bucket}, ".(int)$enabled.", [], '$comment'): [%s] %s", - $rest->error['code'], $rest->error['message']), __FILE__, __LINE__); - return false; - } elseif ($rest->body instanceof SimpleXMLElement) - return self::__parseCloudFrontDistributionConfig($rest->body); - return false; + // TODO: Implement createDistribution() method. } @@ -1355,36 +882,7 @@ public static function createDistribution($bucket, $enabled = true, $cnames = ar */ public static function getDistribution($distributionId) { - if (!extension_loaded('openssl')) - { - self::__triggerError(sprintf("S3::getDistribution($distributionId): %s", - "CloudFront functionality requires SSL"), __FILE__, __LINE__); - return false; - } - $useSSL = self::$useSSL; - - self::$useSSL = true; // CloudFront requires SSL - $rest = new S3Request('GET', '', '2010-11-01/distribution/'.$distributionId, 'cloudfront.amazonaws.com'); - $rest = self::__getCloudFrontResponse($rest); - - self::$useSSL = $useSSL; - - if ($rest->error === false && $rest->code !== 200) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) - { - self::__triggerError(sprintf("S3::getDistribution($distributionId): [%s] %s", - $rest->error['code'], $rest->error['message']), __FILE__, __LINE__); - return false; - } - elseif ($rest->body instanceof SimpleXMLElement) - { - $dist = self::__parseCloudFrontDistributionConfig($rest->body); - $dist['hash'] = $rest->headers['hash']; - $dist['id'] = $distributionId; - return $dist; - } - return false; + // TODO: Implement getDistribution() method. } @@ -1396,47 +894,7 @@ public static function getDistribution($distributionId) */ public static function updateDistribution($dist) { - if (!extension_loaded('openssl')) - { - self::__triggerError(sprintf("S3::updateDistribution({$dist['id']}): %s", - "CloudFront functionality requires SSL"), __FILE__, __LINE__); - return false; - } - - $useSSL = self::$useSSL; - - self::$useSSL = true; // CloudFront requires SSL - $rest = new S3Request('PUT', '', '2010-11-01/distribution/'.$dist['id'].'/config', 'cloudfront.amazonaws.com'); - $rest->data = self::__getCloudFrontDistributionConfigXML( - $dist['origin'], - $dist['enabled'], - $dist['comment'], - $dist['callerReference'], - $dist['cnames'], - $dist['defaultRootObject'], - $dist['originAccessIdentity'], - $dist['trustedSigners'] - ); - - $rest->size = strlen($rest->data); - $rest->setHeader('If-Match', $dist['hash']); - $rest = self::__getCloudFrontResponse($rest); - - self::$useSSL = $useSSL; - - if ($rest->error === false && $rest->code !== 200) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) - { - self::__triggerError(sprintf("S3::updateDistribution({$dist['id']}): [%s] %s", - $rest->error['code'], $rest->error['message']), __FILE__, __LINE__); - return false; - } else { - $dist = self::__parseCloudFrontDistributionConfig($rest->body); - $dist['hash'] = $rest->headers['hash']; - return $dist; - } - return false; + // TODO: Implement updateDistribution() method. } @@ -1448,31 +906,7 @@ public static function updateDistribution($dist) */ public static function deleteDistribution($dist) { - if (!extension_loaded('openssl')) - { - self::__triggerError(sprintf("S3::deleteDistribution({$dist['id']}): %s", - "CloudFront functionality requires SSL"), __FILE__, __LINE__); - return false; - } - - $useSSL = self::$useSSL; - - self::$useSSL = true; // CloudFront requires SSL - $rest = new S3Request('DELETE', '', '2008-06-30/distribution/'.$dist['id'], 'cloudfront.amazonaws.com'); - $rest->setHeader('If-Match', $dist['hash']); - $rest = self::__getCloudFrontResponse($rest); - - self::$useSSL = $useSSL; - - if ($rest->error === false && $rest->code !== 204) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) - { - self::__triggerError(sprintf("S3::deleteDistribution({$dist['id']}): [%s] %s", - $rest->error['code'], $rest->error['message']), __FILE__, __LINE__); - return false; - } - return true; + // TODO: Implement deleteDistribution() method. } @@ -1483,42 +917,7 @@ public static function deleteDistribution($dist) */ public static function listDistributions() { - if (!extension_loaded('openssl')) - { - self::__triggerError(sprintf("S3::listDistributions(): [%s] %s", - "CloudFront functionality requires SSL"), __FILE__, __LINE__); - return false; - } - - $useSSL = self::$useSSL; - self::$useSSL = true; // CloudFront requires SSL - $rest = new S3Request('GET', '', '2010-11-01/distribution', 'cloudfront.amazonaws.com'); - $rest = self::__getCloudFrontResponse($rest); - self::$useSSL = $useSSL; - - if ($rest->error === false && $rest->code !== 200) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) - { - self::__triggerError(sprintf("S3::listDistributions(): [%s] %s", - $rest->error['code'], $rest->error['message']), __FILE__, __LINE__); - return false; - } - elseif ($rest->body instanceof SimpleXMLElement && isset($rest->body->DistributionSummary)) - { - $list = array(); - if (isset($rest->body->Marker, $rest->body->MaxItems, $rest->body->IsTruncated)) - { - //$info['marker'] = (string)$rest->body->Marker; - //$info['maxItems'] = (int)$rest->body->MaxItems; - //$info['isTruncated'] = (string)$rest->body->IsTruncated == 'true' ? true : false; - } - foreach ($rest->body->DistributionSummary as $summary) - $list[(string)$summary->Id] = self::__parseCloudFrontDistributionConfig($summary); - - return $list; - } - return array(); + // TODO: Implement listDistributions() method. } /** @@ -1528,36 +927,7 @@ public static function listDistributions() */ public static function listOriginAccessIdentities() { - if (!extension_loaded('openssl')) - { - self::__triggerError(sprintf("S3::listOriginAccessIdentities(): [%s] %s", - "CloudFront functionality requires SSL"), __FILE__, __LINE__); - return false; - } - - self::$useSSL = true; // CloudFront requires SSL - $rest = new S3Request('GET', '', '2010-11-01/origin-access-identity/cloudfront', 'cloudfront.amazonaws.com'); - $rest = self::__getCloudFrontResponse($rest); - $useSSL = self::$useSSL; - - if ($rest->error === false && $rest->code !== 200) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) - { - trigger_error(sprintf("S3::listOriginAccessIdentities(): [%s] %s", - $rest->error['code'], $rest->error['message']), E_USER_WARNING); - return false; - } - - if (isset($rest->body->CloudFrontOriginAccessIdentitySummary)) - { - $identities = array(); - foreach ($rest->body->CloudFrontOriginAccessIdentitySummary as $identity) - if (isset($identity->S3CanonicalUserId)) - $identities[(string)$identity->Id] = array('id' => (string)$identity->Id, 's3CanonicalUserId' => (string)$identity->S3CanonicalUserId); - return $identities; - } - return false; + // TODO: Implement listOriginAccessIdentities() method. } @@ -1572,30 +942,7 @@ public static function listOriginAccessIdentities() */ public static function invalidateDistribution($distributionId, $paths) { - if (!extension_loaded('openssl')) - { - self::__triggerError(sprintf("S3::invalidateDistribution(): [%s] %s", - "CloudFront functionality requires SSL"), __FILE__, __LINE__); - return false; - } - - $useSSL = self::$useSSL; - self::$useSSL = true; // CloudFront requires SSL - $rest = new S3Request('POST', '', '2010-08-01/distribution/'.$distributionId.'/invalidation', 'cloudfront.amazonaws.com'); - $rest->data = self::__getCloudFrontInvalidationBatchXML($paths, (string)microtime(true)); - $rest->size = strlen($rest->data); - $rest = self::__getCloudFrontResponse($rest); - self::$useSSL = $useSSL; - - if ($rest->error === false && $rest->code !== 201) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) - { - trigger_error(sprintf("S3::invalidate('{$distributionId}',{$paths}): [%s] %s", - $rest->error['code'], $rest->error['message']), E_USER_WARNING); - return false; - } - return true; + // TODO: Implement invalidateDistribution() method. } @@ -1609,15 +956,7 @@ public static function invalidateDistribution($distributionId, $paths) */ private static function __getCloudFrontInvalidationBatchXML($paths, $callerReference = '0') { - $dom = new DOMDocument('1.0', 'UTF-8'); - $dom->formatOutput = true; - $invalidationBatch = $dom->createElement('InvalidationBatch'); - foreach ($paths as $path) - $invalidationBatch->appendChild($dom->createElement('Path', $path)); - - $invalidationBatch->appendChild($dom->createElement('CallerReference', $callerReference)); - $dom->appendChild($invalidationBatch); - return $dom->saveXML(); + // TODO: Implement __getCloudFrontInvalidationBatchXML() method. } @@ -1639,36 +978,7 @@ private static function __getCloudFrontInvalidationBatchXML($paths, $callerRefer */ public static function getDistributionInvalidationList($distributionId) { - if (!extension_loaded('openssl')) - { - self::__triggerError(sprintf("S3::getDistributionInvalidationList(): [%s] %s", - "CloudFront functionality requires SSL"), __FILE__, __LINE__); - return false; - } - - $useSSL = self::$useSSL; - self::$useSSL = true; // CloudFront requires SSL - $rest = new S3Request('GET', '', '2010-11-01/distribution/'.$distributionId.'/invalidation', 'cloudfront.amazonaws.com'); - $rest = self::__getCloudFrontResponse($rest); - self::$useSSL = $useSSL; - - if ($rest->error === false && $rest->code !== 200) - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); - if ($rest->error !== false) - { - trigger_error(sprintf("S3::getDistributionInvalidationList('{$distributionId}'): [%s]", - $rest->error['code'], $rest->error['message']), E_USER_WARNING); - return false; - } - elseif ($rest->body instanceof SimpleXMLElement && isset($rest->body->InvalidationSummary)) - { - $list = array(); - foreach ($rest->body->InvalidationSummary as $summary) - $list[(string)$summary->Id] = (string)$summary->Status; - - return $list; - } - return array(); + // TODO: Implement getDistributionInvalidationList() method. } @@ -1690,32 +1000,7 @@ public static function getDistributionInvalidationList($distributionId) */ private static function __getCloudFrontDistributionConfigXML($bucket, $enabled, $comment, $callerReference = '0', $cnames = array(), $defaultRootObject = null, $originAccessIdentity = null, $trustedSigners = array()) { - $dom = new DOMDocument('1.0', 'UTF-8'); - $dom->formatOutput = true; - $distributionConfig = $dom->createElement('DistributionConfig'); - $distributionConfig->setAttribute('xmlns', 'http://cloudfront.amazonaws.com/doc/2010-11-01/'); - - $origin = $dom->createElement('S3Origin'); - $origin->appendChild($dom->createElement('DNSName', $bucket)); - if ($originAccessIdentity !== null) $origin->appendChild($dom->createElement('OriginAccessIdentity', $originAccessIdentity)); - $distributionConfig->appendChild($origin); - - if ($defaultRootObject !== null) $distributionConfig->appendChild($dom->createElement('DefaultRootObject', $defaultRootObject)); - - $distributionConfig->appendChild($dom->createElement('CallerReference', $callerReference)); - foreach ($cnames as $cname) - $distributionConfig->appendChild($dom->createElement('CNAME', $cname)); - if ($comment !== '') $distributionConfig->appendChild($dom->createElement('Comment', $comment)); - $distributionConfig->appendChild($dom->createElement('Enabled', $enabled ? 'true' : 'false')); - - $trusted = $dom->createElement('TrustedSigners'); - foreach ($trustedSigners as $id => $type) - $trusted->appendChild($id !== '' ? $dom->createElement($type, $id) : $dom->createElement($type)); - $distributionConfig->appendChild($trusted); - - $dom->appendChild($distributionConfig); - //var_dump($dom->saveXML()); - return $dom->saveXML(); + // TODO: Implement __getCloudFrontDistributionConfigXML() method. } @@ -1730,54 +1015,7 @@ private static function __getCloudFrontDistributionConfigXML($bucket, $enabled, */ private static function __parseCloudFrontDistributionConfig(&$node) { - if (isset($node->DistributionConfig)) - return self::__parseCloudFrontDistributionConfig($node->DistributionConfig); - - $dist = array(); - if (isset($node->Id, $node->Status, $node->LastModifiedTime, $node->DomainName)) - { - $dist['id'] = (string)$node->Id; - $dist['status'] = (string)$node->Status; - $dist['time'] = strtotime((string)$node->LastModifiedTime); - $dist['domain'] = (string)$node->DomainName; - } - - if (isset($node->CallerReference)) - $dist['callerReference'] = (string)$node->CallerReference; - - if (isset($node->Enabled)) - $dist['enabled'] = (string)$node->Enabled == 'true' ? true : false; - - if (isset($node->S3Origin)) - { - if (isset($node->S3Origin->DNSName)) - $dist['origin'] = (string)$node->S3Origin->DNSName; - - $dist['originAccessIdentity'] = isset($node->S3Origin->OriginAccessIdentity) ? - (string)$node->S3Origin->OriginAccessIdentity : null; - } - - $dist['defaultRootObject'] = isset($node->DefaultRootObject) ? (string)$node->DefaultRootObject : null; - - $dist['cnames'] = array(); - if (isset($node->CNAME)) - foreach ($node->CNAME as $cname) - $dist['cnames'][(string)$cname] = (string)$cname; - - $dist['trustedSigners'] = array(); - if (isset($node->TrustedSigners)) - foreach ($node->TrustedSigners as $signer) - { - if (isset($signer->Self)) - $dist['trustedSigners'][''] = 'Self'; - elseif (isset($signer->KeyPairId)) - $dist['trustedSigners'][(string)$signer->KeyPairId] = 'KeyPairId'; - elseif (isset($signer->AwsAccountNumber)) - $dist['trustedSigners'][(string)$signer->AwsAccountNumber] = 'AwsAccountNumber'; - } - - $dist['comment'] = isset($node->Comment) ? (string)$node->Comment : null; - return $dist; + // TODO: Implement __parseCloudFrontDistributionConfig() method. } @@ -1790,23 +1028,7 @@ private static function __parseCloudFrontDistributionConfig(&$node) */ private static function __getCloudFrontResponse(&$rest) { - $rest->getResponse(); - if ($rest->response->error === false && isset($rest->response->body) && - is_string($rest->response->body) && substr($rest->response->body, 0, 5) == 'response->body = simplexml_load_string($rest->response->body); - // Grab CloudFront errors - if (isset($rest->response->body->Error, $rest->response->body->Error->Code, - $rest->response->body->Error->Message)) - { - $rest->response->error = array( - 'code' => (string)$rest->response->body->Error->Code, - 'message' => (string)$rest->response->body->Error->Message - ); - unset($rest->response->body); - } - } - return $rest->response; + // TODO: Implement __getCloudFrontResponse() method. } @@ -1874,39 +1096,6 @@ public static function __getTime() { return time() + self::$__timeOffset; } - - - /** - * Generate the auth string: "AWS AccessKey:Signature" - * - * @internal Used by S3Request::getResponse() - * @param string $string String to sign - * @return string - */ - public static function __getSignature($string) - { - return 'AWS '.self::$__accessKey.':'.self::__getHash($string); - } - - - /** - * Creates a HMAC-SHA1 hash - * - * This uses the hash extension if loaded - * - * @internal Used by __getSignature() - * @param string $string String to sign - * @return string - */ - private static function __getHash($string) - { - return base64_encode(extension_loaded('hash') ? - hash_hmac('sha1', $string, self::$__secretKey, true) : pack('H*', sha1( - (str_pad(self::$__secretKey, 64, chr(0x00)) ^ (str_repeat(chr(0x5c), 64))) . - pack('H*', sha1((str_pad(self::$__secretKey, 64, chr(0x00)) ^ - (str_repeat(chr(0x36), 64))) . $string))))); - } - } /** @@ -2107,174 +1296,6 @@ public function setAmzHeader($key, $value) $this->amzHeaders[$key] = $value; } - - /** - * Get the S3 response - * - * @return object | false - */ - public function getResponse() - { - $query = ''; - if (sizeof($this->parameters) > 0) - { - $query = substr($this->uri, -1) !== '?' ? '?' : '&'; - foreach ($this->parameters as $var => $value) - if ($value == null || $value == '') $query .= $var.'&'; - else $query .= $var.'='.rawurlencode($value).'&'; - $query = substr($query, 0, -1); - $this->uri .= $query; - - if (array_key_exists('acl', $this->parameters) || - array_key_exists('location', $this->parameters) || - array_key_exists('torrent', $this->parameters) || - array_key_exists('website', $this->parameters) || - array_key_exists('logging', $this->parameters)) - $this->resource .= $query; - } - $url = (S3::$useSSL ? 'https://' : 'http://') . ($this->headers['Host'] !== '' ? $this->headers['Host'] : $this->endpoint) . $this->uri; - - //var_dump('bucket: ' . $this->bucket, 'uri: ' . $this->uri, 'resource: ' . $this->resource, 'url: ' . $url); - - // Basic setup - $curl = curl_init(); - curl_setopt($curl, CURLOPT_USERAGENT, 'S3/php'); - - if (S3::$useSSL) - { - // Set protocol version - curl_setopt($curl, CURLOPT_SSLVERSION, S3::$useSSLVersion); - - // SSL Validation can now be optional for those with broken OpenSSL installations - curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, S3::$useSSLValidation ? 2 : 0); - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, S3::$useSSLValidation ? 1 : 0); - - if (S3::$sslKey !== null) curl_setopt($curl, CURLOPT_SSLKEY, S3::$sslKey); - if (S3::$sslCert !== null) curl_setopt($curl, CURLOPT_SSLCERT, S3::$sslCert); - if (S3::$sslCACert !== null) curl_setopt($curl, CURLOPT_CAINFO, S3::$sslCACert); - } - - curl_setopt($curl, CURLOPT_URL, $url); - - if (S3::$proxy != null && isset(S3::$proxy['host'])) - { - curl_setopt($curl, CURLOPT_PROXY, S3::$proxy['host']); - curl_setopt($curl, CURLOPT_PROXYTYPE, S3::$proxy['type']); - if (isset(S3::$proxy['user'], S3::$proxy['pass']) && S3::$proxy['user'] != null && S3::$proxy['pass'] != null) - curl_setopt($curl, CURLOPT_PROXYUSERPWD, sprintf('%s:%s', S3::$proxy['user'], S3::$proxy['pass'])); - } - - // Headers - $headers = array(); $amz = array(); - foreach ($this->amzHeaders as $header => $value) - if (strlen($value) > 0) $headers[] = $header.': '.$value; - foreach ($this->headers as $header => $value) - if (strlen($value) > 0) $headers[] = $header.': '.$value; - - // Collect AMZ headers for signature - foreach ($this->amzHeaders as $header => $value) - if (strlen($value) > 0) $amz[] = strtolower($header).':'.$value; - - // AMZ headers must be sorted - if (sizeof($amz) > 0) - { - //sort($amz); - usort($amz, array(&$this, '__sortMetaHeadersCmp')); - $amz = "\n".implode("\n", $amz); - } else $amz = ''; - - if (S3::hasAuth()) - { - // Authorization string (CloudFront stringToSign should only contain a date) - if ($this->headers['Host'] == 'cloudfront.amazonaws.com') - $headers[] = 'Authorization: ' . S3::__getSignature($this->headers['Date']); - else - { - $headers[] = 'Authorization: ' . S3::__getSignature( - $this->verb."\n". - $this->headers['Content-MD5']."\n". - $this->headers['Content-Type']."\n". - $this->headers['Date'].$amz."\n". - $this->resource - ); - } - } - - curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); - curl_setopt($curl, CURLOPT_HEADER, false); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, false); - curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback')); - curl_setopt($curl, CURLOPT_HEADERFUNCTION, array(&$this, '__responseHeaderCallback')); - curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); - - // Request types - switch ($this->verb) - { - case 'GET': break; - case 'PUT': case 'POST': // POST only used for CloudFront - if ($this->fp !== false) - { - curl_setopt($curl, CURLOPT_PUT, true); - curl_setopt($curl, CURLOPT_INFILE, $this->fp); - if ($this->size >= 0) - curl_setopt($curl, CURLOPT_INFILESIZE, $this->size); - } - elseif ($this->data !== false) - { - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb); - curl_setopt($curl, CURLOPT_POSTFIELDS, $this->data); - } - else - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb); - break; - case 'HEAD': - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'HEAD'); - curl_setopt($curl, CURLOPT_NOBODY, true); - break; - case 'DELETE': - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); - break; - default: break; - } - - // Execute, grab errors - if (curl_exec($curl)) - $this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE); - else - $this->response->error = array( - 'code' => curl_errno($curl), - 'message' => curl_error($curl), - 'resource' => $this->resource - ); - - @curl_close($curl); - - // Parse body into XML - if ($this->response->error === false && isset($this->response->headers['type']) && - $this->response->headers['type'] == 'application/xml' && isset($this->response->body)) - { - $this->response->body = simplexml_load_string($this->response->body); - - // Grab S3 errors - if (!in_array($this->response->code, array(200, 204, 206)) && - isset($this->response->body->Code, $this->response->body->Message)) - { - $this->response->error = array( - 'code' => (string)$this->response->body->Code, - 'message' => (string)$this->response->body->Message - ); - if (isset($this->response->body->Resource)) - $this->response->error['resource'] = (string)$this->response->body->Resource; - unset($this->response->body); - } - } - - // Clean up file resources - if ($this->fp !== false && is_resource($this->fp)) fclose($this->fp); - - return $this->response; - } - /** * Sort compare for meta headers * diff --git a/composer.json b/composer.json index 4c55bc10..97011bb4 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,8 @@ } ], "require": { - "php": ">=5.2.0" + "php": ">=5.2.0", + "aws/aws-sdk-php": "3.*" }, "autoload": { "classmap": ["S3.php"] diff --git a/composer.lock b/composer.lock new file mode 100644 index 00000000..3bf1d791 --- /dev/null +++ b/composer.lock @@ -0,0 +1,530 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "78adb5fc553dfe44ee53d6f0a245b954", + "content-hash": "0d6d04130d21c67aa255918d59c4d9db", + "packages": [ + { + "name": "aws/aws-sdk-php", + "version": "3.14.1", + "source": { + "type": "git", + "url": "https://github.com/aws/aws-sdk-php.git", + "reference": "a50b9a66486ad2f27b90521c2250c4c06ae8abea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/a50b9a66486ad2f27b90521c2250c4c06ae8abea", + "reference": "a50b9a66486ad2f27b90521c2250c4c06ae8abea", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "~5.3|~6.0.1|~6.1", + "guzzlehttp/promises": "~1.0", + "guzzlehttp/psr7": "~1.0", + "mtdowling/jmespath.php": "~2.2", + "php": ">=5.5" + }, + "require-dev": { + "andrewsville/php-token-reflection": "^1.4", + "aws/aws-php-sns-message-validator": "~1.0", + "behat/behat": "~3.0", + "doctrine/cache": "~1.4", + "ext-dom": "*", + "ext-json": "*", + "ext-openssl": "*", + "ext-pcre": "*", + "ext-simplexml": "*", + "ext-spl": "*", + "nette/neon": "^2.3", + "phpunit/phpunit": "~4.0|~5.0" + }, + "suggest": { + "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", + "doctrine/cache": "To use the DoctrineCacheAdapter", + "ext-curl": "To send requests using cURL", + "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Aws\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Amazon Web Services", + "homepage": "http://aws.amazon.com" + } + ], + "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", + "homepage": "http://aws.amazon.com/sdkforphp", + "keywords": [ + "amazon", + "aws", + "cloud", + "dynamodb", + "ec2", + "glacier", + "s3", + "sdk" + ], + "time": "2016-01-22 22:32:38" + }, + { + "name": "guzzle/guzzle", + "version": "v3.9.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle3.git", + "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9", + "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.3.3", + "symfony/event-dispatcher": "~2.1" + }, + "replace": { + "guzzle/batch": "self.version", + "guzzle/cache": "self.version", + "guzzle/common": "self.version", + "guzzle/http": "self.version", + "guzzle/inflection": "self.version", + "guzzle/iterator": "self.version", + "guzzle/log": "self.version", + "guzzle/parser": "self.version", + "guzzle/plugin": "self.version", + "guzzle/plugin-async": "self.version", + "guzzle/plugin-backoff": "self.version", + "guzzle/plugin-cache": "self.version", + "guzzle/plugin-cookie": "self.version", + "guzzle/plugin-curlauth": "self.version", + "guzzle/plugin-error-response": "self.version", + "guzzle/plugin-history": "self.version", + "guzzle/plugin-log": "self.version", + "guzzle/plugin-md5": "self.version", + "guzzle/plugin-mock": "self.version", + "guzzle/plugin-oauth": "self.version", + "guzzle/service": "self.version", + "guzzle/stream": "self.version" + }, + "require-dev": { + "doctrine/cache": "~1.3", + "monolog/monolog": "~1.0", + "phpunit/phpunit": "3.7.*", + "psr/log": "~1.0", + "symfony/class-loader": "~2.1", + "zendframework/zend-cache": "2.*,<2.3", + "zendframework/zend-log": "2.*,<2.3" + }, + "suggest": { + "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.9-dev" + } + }, + "autoload": { + "psr-0": { + "Guzzle": "src/", + "Guzzle\\Tests": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Guzzle Community", + "homepage": "https://github.com/guzzle/guzzle/contributors" + } + ], + "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2015-03-18 18:23:50" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.1.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/c6851d6e48f63b69357cbfa55bca116448140e0c", + "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c", + "shasum": "" + }, + "require": { + "guzzlehttp/promises": "~1.0", + "guzzlehttp/psr7": "~1.1", + "php": ">=5.5.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "~4.0", + "psr/log": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.1-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2015-11-23 00:47:50" + }, + { + "name": "guzzlehttp/promises", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/b1e1c0d55f8083c71eda2c28c12a228d708294ea", + "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2015-10-15 22:28:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5d04bdd2881ac89abde1fb78cc234bce24327bb", + "reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "PSR-7 message implementation", + "keywords": [ + "http", + "message", + "stream", + "uri" + ], + "time": "2016-01-23 01:23:02" + }, + { + "name": "mtdowling/jmespath.php", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/jmespath/jmespath.php.git", + "reference": "192f93e43c2c97acde7694993ab171b3de284093" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/192f93e43c2c97acde7694993ab171b3de284093", + "reference": "192f93e43c2c97acde7694993ab171b3de284093", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "bin": [ + "bin/jp.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "JmesPath\\": "src/" + }, + "files": [ + "src/JmesPath.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Declaratively specify how to extract elements from a JSON document", + "keywords": [ + "json", + "jsonpath" + ], + "time": "2016-01-05 18:25:05" + }, + { + "name": "psr/http-message", + "version": "1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", + "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2015-05-04 20:22:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v2.8.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "ee278f7c851533e58ca307f66305ccb9188aceda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ee278f7c851533e58ca307f66305ccb9188aceda", + "reference": "ee278f7c851533e58ca307f66305ccb9188aceda", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.0,>=2.0.5|~3.0.0", + "symfony/dependency-injection": "~2.6|~3.0.0", + "symfony/expression-language": "~2.6|~3.0.0", + "symfony/stopwatch": "~2.3|~3.0.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2016-01-13 10:28:07" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.2.0" + }, + "platform-dev": [] +} diff --git a/example-wrapper.php b/example-wrapper.php index 5ac80fc9..d134f34d 100755 --- a/example-wrapper.php +++ b/example-wrapper.php @@ -6,7 +6,15 @@ * Note: Although this wrapper works, it would be more efficient to use the S3 class instead */ -if (!class_exists('S3')) require_once 'S3.php'; +if(file_exists('vendor/autoload.php')) +{ + require_once 'vendor/autoload.php'; +} + +if (!class_exists('S3')) +{ + require_once 'S3.php'; +} // AWS access info if (!defined('awsAccessKey')) define('awsAccessKey', 'change-this'); @@ -21,173 +29,8 @@ exit("\nERROR: AWS access information required\n\nPlease edit the following lines in this file:\n\n". "define('awsAccessKey', 'change-me');\ndefine('awsSecretKey', 'change-me');\n\n"); - -################################################################################ - - -final class S3Wrapper extends S3 { - private $position = 0, $mode = '', $buffer; - - public function url_stat($path, $flags) { - self::__getURL($path); - return (($info = self::getObjectInfo($this->url['host'], $this->url['path'])) !== false) ? - array('size' => $info['size'], 'mtime' => $info['time'], 'ctime' => $info['time']) : false; - } - - public function unlink($path) { - self::__getURL($path); - return self::deleteObject($this->url['host'], $this->url['path']); - } - - public function mkdir($path, $mode, $options) { - self::__getURL($path); - return self::putBucket($this->url['host'], self::__translateMode($mode)); - } - - public function rmdir($path) { - self::__getURL($path); - return self::deleteBucket($this->url['host']); - } - - public function dir_opendir($path, $options) { - self::__getURL($path); - if (($contents = self::getBucket($this->url['host'], $this->url['path'])) !== false) { - $pathlen = strlen($this->url['path']); - if (substr($this->url['path'], -1) == '/') $pathlen++; - $this->buffer = array(); - foreach ($contents as $file) { - if ($pathlen > 0) $file['name'] = substr($file['name'], $pathlen); - $this->buffer[] = $file; - } - return true; - } - return false; - } - - public function dir_readdir() { - return (isset($this->buffer[$this->position])) ? $this->buffer[$this->position++]['name'] : false; - } - - public function dir_rewinddir() { - $this->position = 0; - } - - public function dir_closedir() { - $this->position = 0; - unset($this->buffer); - } - - public function stream_close() { - if ($this->mode == 'w') { - self::putObject($this->buffer, $this->url['host'], $this->url['path']); - } - $this->position = 0; - unset($this->buffer); - } - - public function stream_stat() { - if (is_object($this->buffer) && isset($this->buffer->headers)) - return array( - 'size' => $this->buffer->headers['size'], - 'mtime' => $this->buffer->headers['time'], - 'ctime' => $this->buffer->headers['time'] - ); - elseif (($info = self::getObjectInfo($this->url['host'], $this->url['path'])) !== false) - return array('size' => $info['size'], 'mtime' => $info['time'], 'ctime' => $info['time']); - return false; - } - - public function stream_flush() { - $this->position = 0; - return true; - } - - public function stream_open($path, $mode, $options, &$opened_path) { - if (!in_array($mode, array('r', 'rb', 'w', 'wb'))) return false; // Mode not supported - $this->mode = substr($mode, 0, 1); - self::__getURL($path); - $this->position = 0; - if ($this->mode == 'r') { - if (($this->buffer = self::getObject($this->url['host'], $this->url['path'])) !== false) { - if (is_object($this->buffer->body)) $this->buffer->body = (string)$this->buffer->body; - } else return false; - } - return true; - } - - public function stream_read($count) { - if ($this->mode !== 'r' && $this->buffer !== false) return false; - $data = substr(is_object($this->buffer) ? $this->buffer->body : $this->buffer, $this->position, $count); - $this->position += strlen($data); - return $data; - } - - public function stream_write($data) { - if ($this->mode !== 'w') return 0; - $left = substr($this->buffer, 0, $this->position); - $right = substr($this->buffer, $this->position + strlen($data)); - $this->buffer = $left . $data . $right; - $this->position += strlen($data); - return strlen($data); - } - - public function stream_tell() { - return $this->position; - } - - public function stream_eof() { - return $this->position >= strlen(is_object($this->buffer) ? $this->buffer->body : $this->buffer); - } - - public function stream_seek($offset, $whence) { - switch ($whence) { - case SEEK_SET: - if ($offset < strlen($this->buffer->body) && $offset >= 0) { - $this->position = $offset; - return true; - } else return false; - break; - case SEEK_CUR: - if ($offset >= 0) { - $this->position += $offset; - return true; - } else return false; - break; - case SEEK_END: - $bytes = strlen($this->buffer->body); - if ($bytes + $offset >= 0) { - $this->position = $bytes + $offset; - return true; - } else return false; - break; - default: return false; - } - } - - private function __getURL($path) { - $this->url = parse_url($path); - if (!isset($this->url['scheme']) || $this->url['scheme'] !== 's3') return $this->url; - if (isset($this->url['user'], $this->url['pass'])) self::setAuth($this->url['user'], $this->url['pass']); - $this->url['path'] = isset($this->url['path']) ? substr($this->url['path'], 1) : ''; - } - - private function __translateMode($mode) { - $acl = self::ACL_PRIVATE; - if (($mode & 0x0020) || ($mode & 0x0004)) - $acl = self::ACL_PUBLIC_READ; - // You probably don't want to enable public write access - if (($mode & 0x0010) || ($mode & 0x0008) || ($mode & 0x0002) || ($mode & 0x0001)) - $acl = self::ACL_PUBLIC_READ; //$acl = self::ACL_PUBLIC_READ_WRITE; - return $acl; - } -} stream_wrapper_register('s3', 'S3Wrapper'); - - -################################################################################ - - S3::setAuth(awsAccessKey, awsSecretKey); - +S3::registerStreamWrapper(); $bucketName = uniqid('s3test');