Skip to content

Commit

Permalink
finish refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
albertcht committed Oct 27, 2017
1 parent 4be2dff commit 693ec3f
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 49 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"php": "^5.6.4 || ^7.0",
"aws/aws-sdk-php": "^3.31",
"illuminate/support": ">=5.0.0",
"guzzlehttp/guzzle": "^6.2"
"guzzlehttp/guzzle": "^6.2",
"mockery/mockery": "0.9.*"
},
"require-dev": {
"phpunit/phpunit": "^6.1"
Expand Down
52 changes: 29 additions & 23 deletions src/S3Presigned.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@
class S3Presigned
{
protected $client;
protected $region;
protected $options;
protected $requiredOptions = ['region'];
protected $requiredOptions = [];
protected $baseUri;
protected $prefix;

public function __construct(S3Client $client, $bucket, $prefix = '', array $options = [])
public function __construct(S3Client $client, $region, $bucket, $prefix = '', array $options = [])
{
$this->client = $client;
$this->bucket = $bucket;
$this->region = $region;
$this->options = $options;
$this->checkOptions();
$this->setBaseUri();
Expand Down Expand Up @@ -64,25 +66,30 @@ public function getUploadForm($key, $minutes = 10, array $policies = [], array $
];
}

public function listObjects()
public function listObjects($directory = '', $recursive = false)
{
// http://docs.aws.amazon.com/AmazonS3/latest/dev/ListingObjectKeysUsingPHP.html
// http://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#listobjects
// https://github.com/thephpleague/flysystem-aws-s3-v3/blob/master/src/AwsS3Adapter.php
$resultPaginator = $this->client->getPaginator('ListObjects', [
$options = [
'Bucket' => $this->getBucket(),
'Prefix' => $this->getPrefix()
]);
];
if ($recursive === false) {
$options['Delimiter'] = '/';
}
$listing = $this->retrievePaginatedListing($options);
$normalized = array_map([$this, 'normalizeObject'], $listing);

return $normalized;
}

protected function retrievePaginatedListing(array $options)
{
$resultPaginator = $this->client->getPaginator('ListObjects', $options);

$listing = [];
foreach ($resultPaginator as $result) {
$objects = $result->get('Contents');
if (is_null($objects)) {
continue;
}
foreach ($objects as $object) {
$listing[] = $this->normalizeObject($object);
}
$listing = array_merge($result->get('Contents') ?: [], $result->get('CommonPrefixes') ?: []);
}

return $listing;
Expand All @@ -96,17 +103,17 @@ public function deleteObject($key)
]);
}

private function normalizeObject(array $object)
protected function normalizeObject(array $object)
{
$normalized = [];
$normalized['key'] = $object['Key'] ?? '';
$normalized['url'] = $this->baseUri . $normalized['key'];
$normalized['size'] = $object['Size'] ?? '';
if (array_key_exists('LastModified', $object)) {
$object['Timestamp'] = strtotime($object['LastModified']);
}
$object['Url'] = $this->getBaseUri() . $object['Key'];

return $normalized;
return $object;
}

private function getPostObject(array $defaults, array $options, $minutes = 10)
protected function getPostObject(array $defaults, array $options, $minutes = 10)
{
return new PostObjectV4(
$this->getClient(),
Expand All @@ -117,7 +124,7 @@ private function getPostObject(array $defaults, array $options, $minutes = 10)
);
}

public function checkOptions()
protected function checkOptions()
{
$missings = array_filter($this->requiredOptions, function ($value) {
return !array_key_exists($value, $this->options);
Expand All @@ -130,8 +137,7 @@ public function checkOptions()

public function setBaseUri()
{
$baseUri = "https://{$this->bucket}.s3-{$this->options['region']}.amazonaws.com/";
$this->baseUri = $baseUri;
$this->baseUri = "https://{$this->bucket}.s3-{$this->region}.amazonaws.com/";

return $this;
}
Expand Down
12 changes: 9 additions & 3 deletions src/S3PresignedServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,18 @@ public function register()
'version' => $configs['version']
'credentials' => $credentials,
'options' => [
$configs['options']
$configs['s3_client']['options']
]
]);

$this->app->singleton('s3.presigned', function ($app) use ($s3Client, $configs) {
return new S3Presigned($s3Client, $configs['bucket'], $configs['prefix'], $configs)
return new S3Presigned(
$s3Client,
$configs['region'],
$configs['bucket'],
$configs['prefix'],
$configs['options']
);
});
}

Expand All @@ -55,7 +61,7 @@ public function register()
*/
protected function bootConfig()
{
$path = __DIR__.'/config/captcha.php';
$path = __DIR__ . '/config/captcha.php';
$this->mergeConfigFrom($path, 's3_presigned');
if (function_exists('config_path')) {
$this->publishes([$path => config_path('s3_presigned.php')]);
Expand Down
3 changes: 3 additions & 0 deletions src/config/s3_presigned.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
'version' => env('AWS_VERSION', 'latest'),
'bucket' => env('AWS_S3_BUCKET'),
'prefix' => env('AWS_S3_PREFIX', ''),
's3_client' => [
'options' => []
],
'options' => [
//
]
Expand Down
99 changes: 77 additions & 22 deletions tests/PresignedTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

namespace Tests;

use Illuminate\Container\Container;
use Illuminate\Filesystem\Filesystem;
use Mockery as m;
use PHPUnit\Framework\TestCase;
use Aws\Credentials\Credentials;
use Aws\S3\S3Client;
use Aws\S3\PostObjectV4;
use Aws\Api\DateTimeResult;
use Unisharp\S3\Presigned\S3PresignedServiceProvider;
use Unisharp\S3\Presigned\S3Presigned;
use Unisharp\S3\Presigned\Exceptions\OptionsMissingException;
Expand All @@ -22,6 +23,9 @@ class PresignedTest extends TestCase
'version' => 'latest',
'bucket' => 'bucket',
'prefix' => 'prefix/',
's3_client' => [
'options' => []
],
'options' => [
'foo' => 'bar'
]
Expand All @@ -32,18 +36,18 @@ protected function setUp()
parent::setUp();
}

public function testCheckOptions()
{
$options = [
'bucket' => 'bucket',
'prefix' => 'prefix/',
'options' => [
'foo' => 'bar'
]
];
$this->expectException(OptionsMissingException::class);
$s3Presigned = $this->getS3Presigned($options);
}
// public function testCheckOptions()
// {
// $configs = [
// 'bucket' => 'bucket',
// 'prefix' => 'prefix/',
// 'options' => [
// 'foo' => 'bar'
// ]
// ];
// $this->expectException(OptionsMissingException::class);
// $s3Presigned = $this->getS3Presigned($configs);
// }

public function testSetPrefix()
{
Expand Down Expand Up @@ -85,24 +89,75 @@ public function testGetUploadForm()
$this->assertEquals($result['inputs']['foo'], 'bar');
}

private function getS3Presigned($options = [])
public function testListObjects()
{
$number = 10;
$url = "https://{$this->configs['bucket']}.s3-ap-northeast-1.amazonaws.com/public/";
$s3Client = m::mock(S3Client::class);
$s3Client->shouldReceive('getPaginator')
->once()
->with('ListObjects', m::type('array'))
->andReturn([$this->getMockedObjects($number)]);

$s3Presigned = $this->getS3Presigned([], $s3Client);
$objects = $s3Presigned->listObjects();
$this->assertEquals($number , count($objects));
$this->assertEquals($url, $objects[0]['Url']);
}

protected function getMockedObjects($number = 5)
{
$objects = m::mock(\stdObject::class);
$objects->shouldReceive('get')
->once()
->with('Contents')
->andReturn(array_fill(0, $number, [
'Key' => 'public/',
'LastModified' => DateTimeResult::fromEpoch(time()),
'ETag' => 'etag',
'Size' => 0,
'StorageClass' => 'STANDARD',
'Owner' => [
'DisplayName' => 'seafood',
'ID' => 'owner_id',
]
]));
$objects->shouldReceive('get')
->once()
->with('CommonPrefixes')
->andReturn([]);

return $objects;
}

protected function getS3Presigned(array $configs = [], S3Client $s3Client = null)
{
$configs = array_merge($this->configs, $configs);
$s3Client = $s3Client ? $s3Client : $this->getS3Client($configs);

return new S3Presigned(
$s3Client,
$configs['region'],
$configs['bucket'],
$configs['prefix'],
$configs['options']
);
}

protected function getS3Client(array $configs)
{
$configs = $this->configs;
$credentials = new Credentials(
$configs['credentials']['access_key'],
$configs['credentials']['secret_key']
);
$s3Client = new S3Client([

return new S3Client([
'region' => $configs['region'],
'version' => $configs['version'],
'credentials' => $credentials,
'options' => [
$configs['options']
$configs['s3_client']['options']
]
]);

$options = $options ?: $configs;

return new S3Presigned($s3Client, $options['bucket'], $options['prefix'], $options);
}
}

0 comments on commit 693ec3f

Please sign in to comment.