1
0

initial commit

This commit is contained in:
frostealth
2016-04-08 15:50:37 +06:00
commit 9cfd06866e
40 changed files with 2312 additions and 0 deletions

273
src/Service.php Normal file
View File

@@ -0,0 +1,273 @@
<?php
namespace frostealth\yii2\aws\s3;
use Aws\ResultInterface;
use frostealth\yii2\aws\s3\base\CommandFactory;
use frostealth\yii2\aws\s3\interfaces\commands\Command;
use frostealth\yii2\aws\s3\interfaces\HandlerResolver;
use frostealth\yii2\aws\s3\interfaces\Service as ServiceInterface;
use yii\base\Component;
use yii\base\InvalidConfigException;
use yii\helpers\ArrayHelper;
/**
* Class Service
*
* @property HandlerResolver $resolver
*
* @method ResultInterface get(string $filename)
* @method ResultInterface put(string $filename, $body)
* @method ResultInterface delete(string $filename)
* @method ResultInterface upload(string $filename, $source)
* @method ResultInterface restore(string $filename, int $days)
* @method bool exist(string $filename)
* @method string getUrl(string $filename)
* @method string getPresignedUrl(string $filename, $expires)
*
* @package frostealth\yii2\aws\s3
*/
class Service extends Component implements ServiceInterface
{
const ACL_PRIVATE = 'private';
const ACL_PUBLIC_READ = 'public-read';
const ACL_PUBLIC_READ_WRITE = 'public-read-write';
const ACL_AWS_EXEC_READ = 'aws-exec-read';
const ACL_AUTHENTICATED_READ = 'authenticated-read';
const ACL_BUCKET_OWNER_READ = 'bucket-owner-read';
const ALC_BUCKET_OWNER_FULL_CONTROL = 'bucket-owner-full-control';
/** @var string */
public $defaultBucket;
/** @var string */
public $defaultAcl = '';
/** @var array S3Client config */
protected $clientConfig = ['version' => '2006-03-01'];
/** @var array */
private $components = [];
/** @var array */
private $definitions = [
'client' => ['class' => 'Aws\S3\S3Client'],
'resolver' => ['class' => 'frostealth\yii2\aws\s3\base\HandlerResolver'],
'bus' => ['class' => 'frostealth\yii2\aws\s3\base\Bus'],
'builder' => ['class' => 'frostealth\yii2\aws\s3\base\CommandBuilder'],
'factory' => ['class' => 'frostealth\yii2\aws\s3\base\CommandFactory'],
];
/**
* Initializes the object.
* This method is invoked at the end of the constructor after the object is initialized with the
* given configuration.
*/
public function init()
{
if (empty($this->clientConfig['credentials'])) {
throw new InvalidConfigException('Credentials is not set.');
}
if (empty($this->clientConfig['region'])) {
throw new InvalidConfigException('Region is not set.');
}
if (empty($this->defaultBucket)) {
throw new InvalidConfigException('Default bucket name is not set.');
}
foreach ($this->definitions as $name => $definition) {
$this->components[$name] = $this->components[$name] ?? $definition;
}
}
/**
* Executes a command.
*
* @param \frostealth\yii2\aws\s3\interfaces\commands\Command $command
*
* @return mixed
*/
public function execute(Command $command)
{
return $this->getComponent('bus')->execute($command);
}
/**
* Creates a command with default params.
*
* @param string $commandClass
*
* @return \frostealth\yii2\aws\s3\interfaces\commands\Command
*/
public function create(string $commandClass): Command
{
return $this->getComponent('builder')->build($commandClass);
}
/**
* Returns command factory.
*
* @return \frostealth\yii2\aws\s3\base\CommandFactory
*/
public function commands(): CommandFactory
{
return $this->getComponent('factory');
}
/**
* Returns handler resolver.
*
* @return \frostealth\yii2\aws\s3\interfaces\HandlerResolver
*/
public function getResolver(): HandlerResolver
{
return $this->getComponent('resolver');
}
/**
* @param string $name
* @param array $params
*
* @return mixed
*/
public function __call($name, $params)
{
if (method_exists($this->commands(), $name)) {
$result = call_user_func_array([$this->commands(), $name], $params);
return $result instanceof Command ? $this->execute($result) : $result;
}
return parent::__call($name, $params);
}
/**
* @param \Aws\Credentials\CredentialsInterface|array|callable $credentials
*/
public function setCredentials($credentials)
{
$this->clientConfig['credentials'] = $credentials;
}
/**
* @param string $region
*/
public function setRegion(string $region)
{
$this->clientConfig['region'] = $region;
}
/**
* @param array|bool $debug
*/
public function setDebug($debug)
{
$this->clientConfig['debug'] = $debug;
}
/**
* @param string|array|object $resolver
*/
public function setResolver($resolver)
{
$this->setComponent('resolver', $resolver);
}
/**
* @param string|array|object $bus
*/
public function setBus($bus)
{
$this->setComponent('bus', $bus);
}
/**
* @param string|array|object $builder
*/
public function setBuilder($builder)
{
$this->setComponent('builder', $builder);
}
/**
* @param string|array|object $factory
*/
public function setFactory($factory)
{
$this->setComponent('factory', $factory);
}
/**
* @param string $name
*
* @return object
*/
protected function getComponent(string $name)
{
if (!is_object($this->components[$name])) {
$this->components[$name] = $this->createComponent($name);
}
return $this->components[$name];
}
/**
* @param string $name
* @param array|object|string $definition
*/
protected function setComponent(string $name, $definition)
{
if (!is_object($definition)) {
$definition = !is_array($definition) ? ['class' => $definition] : $definition;
$definition = ArrayHelper::merge($this->definitions[$name], $definition);
}
$this->components[$name] = $definition;
}
/**
* @param string $name
*
* @return object
* @throws \yii\base\InvalidConfigException
*/
protected function createComponent(string $name)
{
$definition = $this->components[$name];
$params = $this->getComponentParams($name);
return \Yii::createObject($definition, $params);
}
/**
* @param string $name
*
* @return array
*/
protected function getComponentParams(string $name): array
{
switch ($name) {
case 'client':
$params = [$this->clientConfig];
break;
case 'resolver':
$params = [$this->getComponent('client')];
break;
case 'bus':
$params = [$this->getComponent('resolver')];
break;
case 'builder':
$params = [$this->getComponent('bus'), $this->defaultBucket, $this->defaultAcl];
break;
case 'factory':
$params = [$this->getComponent('builder')];
break;
default:
$params = [];
}
return $params;
}
}

38
src/base/Bus.php Normal file
View File

@@ -0,0 +1,38 @@
<?php
namespace frostealth\yii2\aws\s3\base;
use frostealth\yii2\aws\s3\interfaces;
/**
* Class Bus
*
* @package frostealth\yii2\aws\s3\base
*/
class Bus implements interfaces\Bus
{
/** @var interfaces\HandlerResolver */
protected $resolver;
/**
* Bus constructor.
*
* @param \frostealth\yii2\aws\s3\interfaces\HandlerResolver $inflector
*/
public function __construct(interfaces\HandlerResolver $inflector)
{
$this->resolver = $inflector;
}
/**
* @param \frostealth\yii2\aws\s3\interfaces\commands\Command $command
*
* @return mixed
*/
public function execute(interfaces\commands\Command $command)
{
$handler = $this->resolver->resolve($command);
return call_user_func([$handler, 'handle'], $command);
}
}

View File

@@ -0,0 +1,68 @@
<?php
namespace frostealth\yii2\aws\s3\base;
use frostealth\yii2\aws\s3\interfaces;
/**
* Class CommandBuilder
*
* @package frostealth\yii2\aws\s3\base
*/
class CommandBuilder implements interfaces\CommandBuilder
{
/** @var string default bucket name */
protected $bucket;
/** @var string default acl */
protected $acl;
/** @var interfaces\Bus */
protected $bus;
/**
* CommandBuilder constructor.
*
* @param \frostealth\yii2\aws\s3\interfaces\Bus $bus
* @param string $bucket
* @param string $acl
*/
public function __construct(interfaces\Bus $bus, string $bucket = '', string $acl = '')
{
$this->bus = $bus;
$this->bucket = $bucket;
$this->acl = $acl;
}
/**
* @param string $className
*
* @return \frostealth\yii2\aws\s3\interfaces\commands\Command
* @throws \yii\base\InvalidConfigException
*/
public function build(string $className): interfaces\commands\Command
{
$params = is_subclass_of($className, interfaces\commands\ExecutableCommand::class) ? [$this->bus] : [];
/** @var interfaces\commands\Command $command */
$command = \Yii::createObject($className, $params);
$this->prepareCommand($command);
return $command;
}
/**
* @param \frostealth\yii2\aws\s3\interfaces\commands\Command $command
*/
protected function prepareCommand(interfaces\commands\Command $command)
{
if ($command instanceof interfaces\commands\HasBucket) {
$command->setBucket($this->bucket);
}
if ($command instanceof interfaces\commands\HasAcl) {
$command->setAcl($this->acl);
}
}
}

160
src/base/CommandFactory.php Normal file
View File

@@ -0,0 +1,160 @@
<?php
namespace frostealth\yii2\aws\s3\base;
use frostealth\yii2\aws\s3\commands\DeleteCommand;
use frostealth\yii2\aws\s3\commands\ExistCommand;
use frostealth\yii2\aws\s3\commands\GetCommand;
use frostealth\yii2\aws\s3\commands\GetPresignedUrlCommand;
use frostealth\yii2\aws\s3\commands\GetUrlCommand;
use frostealth\yii2\aws\s3\commands\PutCommand;
use frostealth\yii2\aws\s3\commands\RestoreCommand;
use frostealth\yii2\aws\s3\commands\UploadCommand;
use frostealth\yii2\aws\s3\interfaces;
/**
* Class CommandFactory
*
* @package frostealth\yii2\aws\s3\base
*/
class CommandFactory
{
/** @var \frostealth\yii2\aws\s3\interfaces\CommandBuilder */
private $builder;
/**
* CommandFactory constructor.
*
* @param \frostealth\yii2\aws\s3\interfaces\CommandBuilder $builder
*/
public function __construct(interfaces\CommandBuilder $builder)
{
$this->builder = $builder;
}
/**
* @param string $filename
*
* @return \frostealth\yii2\aws\s3\commands\GetCommand
*/
public function get(string $filename): GetCommand
{
/** @var GetCommand $command */
$command = $this->builder->build(GetCommand::class);
$command->setFilename($filename);
return $command;
}
/**
* @param string $filename
* @param mixed $body
*
* @return \frostealth\yii2\aws\s3\commands\PutCommand
*/
public function put(string $filename, $body): PutCommand
{
/** @var PutCommand $command */
$command = $this->builder->build(PutCommand::class);
$command->setFilename($filename)->setBody($body);
return $command;
}
/**
* @param string $filename
*
* @return \frostealth\yii2\aws\s3\commands\DeleteCommand
*/
public function delete(string $filename): DeleteCommand
{
/** @var DeleteCommand $command */
$command = $this->builder->build(DeleteCommand::class);
$command->setFilename($filename);
return $command;
}
/**
* @param string $filename
* @param mixed $source
*
* @return \frostealth\yii2\aws\s3\commands\UploadCommand
*/
public function upload(string $filename, $source): UploadCommand
{
/** @var UploadCommand $command */
$command = $this->builder->build(UploadCommand::class);
$command->setFilename($filename)->setSource($source);
return $command;
}
/**
* @param string $filename
* @param int $days lifetime of the active copy in days
*
* @return \frostealth\yii2\aws\s3\commands\RestoreCommand
*/
public function restore(string $filename, int $days): RestoreCommand
{
/** @var RestoreCommand $command */
$command = $this->builder->build(RestoreCommand::class);
$command->setFilename($filename)->setDays($days);
return $command;
}
/**
* @param string $filename
*
* @return \frostealth\yii2\aws\s3\commands\ExistCommand
*/
public function exist(string $filename): ExistCommand
{
/** @var ExistCommand $command */
$command = $this->builder->build(ExistCommand::class);
$command->setFilename($filename);
return $command;
}
/**
* @param string $filename
*
* @return \frostealth\yii2\aws\s3\commands\GetUrlCommand
*/
public function getUrl(string $filename): GetUrlCommand
{
/** @var GetUrlCommand $command */
$command = $this->builder->build(GetUrlCommand::class);
$command->setFilename($filename);
return $command;
}
/**
* @param string $filename
* @param mixed $expires
*
* @return \frostealth\yii2\aws\s3\commands\GetPresignedUrlCommand
*/
public function getPresignedUrl(string $filename, $expires): GetPresignedUrlCommand
{
/** @var GetPresignedUrlCommand $command */
$command = $this->builder->build(GetPresignedUrlCommand::class);
$command->setFilename($filename)->setExpires($expires);
return $command;
}
/**
* @param string $commandClass
*
* @return \frostealth\yii2\aws\s3\interfaces\commands\Command
*/
final protected function createCommand(string $commandClass)
{
return $this->builder->build($commandClass);
}
}

View File

@@ -0,0 +1,98 @@
<?php
namespace frostealth\yii2\aws\s3\base;
use Aws\S3\S3Client;
use frostealth\yii2\aws\s3\handlers\PlainCommandHandler;
use frostealth\yii2\aws\s3\interfaces;
use yii\base\Exception;
use yii\base\Object;
/**
* Class HandlerResolver
*
* @package frostealth\yii2\aws\s3\base
*/
class HandlerResolver extends Object implements interfaces\HandlerResolver
{
/** @var array */
protected $handlers = [];
/** @var \Aws\S3\S3Client */
protected $s3Client;
/**
* HandlerResolver constructor.
*
* @param \Aws\S3\S3Client $s3Client
* @param array $config
*/
public function __construct(S3Client $s3Client, array $config = [])
{
$this->s3Client = $s3Client;
parent::__construct($config);
}
/**
* @param \frostealth\yii2\aws\s3\interfaces\commands\Command $command
*
* @return \frostealth\yii2\aws\s3\interfaces\handlers\Handler
* @throws \yii\base\Exception
*/
public function resolve(interfaces\commands\Command $command): interfaces\handlers\Handler
{
$commandClass = get_class($command);
if (isset($this->handlers[$commandClass])) {
$handler = $this->handlers[$commandClass];
return is_object($handler) ? $handler : $this->createHandler($handler);
}
if ($command instanceof interfaces\commands\PlainCommand) {
return $this->createHandler(PlainCommandHandler::class);
}
$handlerClass = $commandClass . 'Handler';
if (class_exists($handlerClass)) {
return $this->createHandler($handlerClass);
}
$handlerClass = str_replace('\\commands\\', '\\handlers\\', $handlerClass);
if (class_exists($handlerClass)) {
return $this->createHandler($handlerClass);
}
throw new Exception("Could not terminate the handler of a command of type \"{$commandClass}\"");
}
/**
* @param string $commandClass
* @param mixed $handler
*/
public function bindHandler(string $commandClass, $handler)
{
$this->handlers[$commandClass] = $handler;
}
/**
* @param array $handlers
*/
public function setHandlers(array $handlers)
{
foreach ($handlers as $commandClass => $handler) {
$this->bindHandler($commandClass, $handler);
}
}
/**
* @param string|array $type
*
* @return \frostealth\yii2\aws\s3\interfaces\handlers\Handler
* @throws \yii\base\InvalidConfigException
*/
protected function createHandler($type): interfaces\handlers\Handler
{
return \Yii::createObject($type, [$this->s3Client]);
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace frostealth\yii2\aws\s3\base\commands;
use frostealth\yii2\aws\s3\interfaces\Bus;
use frostealth\yii2\aws\s3\interfaces\commands\ExecutableCommand as ExecutableCommandInterface;
/**
* Class ExecutableCommand
*
* @package frostealth\yii2\aws\s3\base\commands
*/
abstract class ExecutableCommand implements ExecutableCommandInterface
{
/** @var \frostealth\yii2\aws\s3\interfaces\Bus */
private $bus;
/**
* ExecutableCommand constructor.
*
* @param \frostealth\yii2\aws\s3\interfaces\Bus $bus
*/
public function __construct(Bus $bus)
{
$this->bus = $bus;
}
/**
* @return mixed
*/
public function execute()
{
return $this->bus->execute($this);
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace frostealth\yii2\aws\s3\base\commands\traits;
/**
* Trait Async
*
* @package frostealth\yii2\aws\s3\base\commands\traits
*/
trait Async
{
/** @var bool */
private $isAsync = false;
/**
* @param bool $async
*
* @return $this
*/
final public function async(bool $async = true)
{
$this->isAsync = $async;
return $this;
}
/**
* @return bool
*/
final public function isAsync(): bool
{
return $this->isAsync;
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace frostealth\yii2\aws\s3\base\commands\traits;
/**
* Trait Options
*
* @package frostealth\yii2\aws\s3\base\commands\traits
*/
trait Options
{
/** @var array */
protected $options = [];
/**
* @param array $value
*
* @return $this
*/
final public function setOptions(array $value)
{
$this->options = $value;
return $this;
}
/**
* @return array
*/
final public function getOptions(): array
{
return $this->options;
}
/**
* @param string $name
* @param mixed $value
*
* @return $this
*/
final public function setOption(string $name, $value)
{
$this->options[$name] = $value;
return $this;
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace frostealth\yii2\aws\s3\base\handlers;
use Aws\S3\S3Client;
use frostealth\yii2\aws\s3\interfaces\handlers\Handler as HandlerInterface;
/**
* Class Handler
*
* @package frostealth\yii2\aws\s3\base\handlers
*/
abstract class Handler implements HandlerInterface
{
/** @var S3Client */
protected $s3Client;
/**
* Handler constructor.
*
* @param \Aws\S3\S3Client $s3Client
*/
public function __construct(S3Client $s3Client)
{
$this->s3Client = $s3Client;
}
}

View File

@@ -0,0 +1,104 @@
<?php
namespace frostealth\yii2\aws\s3\commands;
use Aws\ResultInterface;
use frostealth\yii2\aws\s3\base\commands\ExecutableCommand;
use frostealth\yii2\aws\s3\base\commands\traits\Async;
use frostealth\yii2\aws\s3\base\commands\traits\Options;
use frostealth\yii2\aws\s3\interfaces\commands\Asynchronous;
use frostealth\yii2\aws\s3\interfaces\commands\HasBucket;
use frostealth\yii2\aws\s3\interfaces\commands\PlainCommand;
use GuzzleHttp\Promise\PromiseInterface;
/**
* Class DeleteCommand
*
* @method ResultInterface|PromiseInterface execute()
*
* @package frostealth\yii2\aws\s3\commands
*/
class DeleteCommand extends ExecutableCommand implements PlainCommand, HasBucket, Asynchronous
{
use Async;
use Options;
/** @var array */
protected $args = [];
/**
* @return string
*/
public function getBucket(): string
{
return $this->args['Bucket'] ?? '';
}
/**
* @param string $bucket
*
* @return $this
*/
public function setBucket(string $bucket)
{
$this->args['Bucket'] = $bucket;
return $this;
}
/**
* @return string
*/
public function getFilename(): string
{
return $this->args['Key'] ?? '';
}
/**
* @param string $filename
*
* @return $this
*/
public function setFilename(string $filename)
{
$this->args['Key'] = $filename;
return $this;
}
/**
* @return string
*/
public function getVersionId(): string
{
return $this->args['VersionId'] ?? '';
}
/**
* @param string $versionId
*
* @return $this
*/
public function setVersionId(string $versionId)
{
$this->args['VersionId'] = $versionId;
return $this;
}
/**
* @return string
*/
public function getName(): string
{
return 'DeleteObject';
}
/**
* @return array
*/
public function toArgs(): array
{
return array_replace($this->options, $this->args);
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace frostealth\yii2\aws\s3\commands;
use frostealth\yii2\aws\s3\base\commands\ExecutableCommand;
use frostealth\yii2\aws\s3\base\commands\traits\Options;
use frostealth\yii2\aws\s3\interfaces\commands\HasBucket;
/**
* Class ExistCommand
*
* @method bool execute()
*
* @package frostealth\yii2\aws\s3\commands
*/
class ExistCommand extends ExecutableCommand implements HasBucket
{
use Options;
/** @var string */
protected $bucket;
/** @var string */
protected $filename;
/**
* @return string
*/
public function getBucket(): string
{
return $this->bucket;
}
/**
* @param string $bucket
*
* @return $this
*/
public function setBucket(string $bucket)
{
$this->bucket = $bucket;
return $this;
}
/**
* @return string
*/
public function getFilename(): string
{
return $this->filename;
}
/**
* @param string $filename
*
* @return $this
*/
public function setFilename(string $filename)
{
$this->filename = $filename;
return $this;
}
}

108
src/commands/GetCommand.php Normal file
View File

@@ -0,0 +1,108 @@
<?php
namespace frostealth\yii2\aws\s3\commands;
use Aws\ResultInterface;
use frostealth\yii2\aws\s3\base\commands\ExecutableCommand;
use frostealth\yii2\aws\s3\base\commands\traits\Async;
use frostealth\yii2\aws\s3\base\commands\traits\Options;
use frostealth\yii2\aws\s3\interfaces\commands\Asynchronous;
use frostealth\yii2\aws\s3\interfaces\commands\HasBucket;
use frostealth\yii2\aws\s3\interfaces\commands\PlainCommand;
use GuzzleHttp\Promise\PromiseInterface;
/**
* Class GetCommand
*
* @method ResultInterface|PromiseInterface execute()
*
* @package frostealth\yii2\aws\s3\commands
*/
class GetCommand extends ExecutableCommand implements PlainCommand, HasBucket, Asynchronous
{
use Async;
use Options;
/** @var array */
protected $args = [];
/**
* @return string
*/
public function getBucket(): string
{
return $this->args['Bucket'] ?? '';
}
/**
* @param string $bucket
*
* @return $this
*/
public function setBucket(string $bucket)
{
$this->args['Bucket'] = $bucket;
return $this;
}
/**
* @return string
*/
public function getFilename(): string
{
return $this->args['Key'] ?? '';
}
/**
* @param string $filename
*
* @return $this
*/
public function setFilename(string $filename)
{
$this->args['Key'] = $filename;
return $this;
}
/**
* @param string $value
*
* @return $this
*/
public function saveAs(string $value)
{
$this->args['SaveAs'] = $value;
return $this;
}
/**
* @param string $ifMatch
*
* @return $this
*/
public function ifMatch(string $ifMatch)
{
$this->args['IfMatch'] = $ifMatch;
return $this;
}
/**
* @return string
*/
public function getName(): string
{
return 'GetObject';
}
/**
* @return array
*/
public function toArgs(): array
{
return array_replace($this->options, $this->args);
}
}

View File

@@ -0,0 +1,90 @@
<?php
namespace frostealth\yii2\aws\s3\commands;
use frostealth\yii2\aws\s3\base\commands\ExecutableCommand;
use frostealth\yii2\aws\s3\interfaces\commands\HasBucket;
/**
* Class GetPresignedUrlCommand
*
* @method string execute()
*
* @package frostealth\yii2\aws\s3\commands
*/
class GetPresignedUrlCommand extends ExecutableCommand implements HasBucket
{
/** @var array */
protected $args = [];
/** @var mixed */
protected $expires;
/**
* @return string
*/
public function getBucket(): string
{
return $this->args['Bucket'] ?? '';
}
/**
* @param string $bucket
*
* @return $this
*/
public function setBucket(string $bucket)
{
$this->args['Bucket'] = $bucket;
return $this;
}
/**
* @return string
*/
public function getFilename(): string
{
return $this->args['Key'] ?? '';
}
/**
* @param string $filename
*
* @return $this
*/
public function setFilename(string $filename)
{
$this->args['Key'] = $filename;
return $this;
}
/**
* @return mixed
*/
public function getExpires()
{
return $this->expires;
}
/**
* @param int|string|\DateTime $expires
*
* @return $this
*/
public function setExpires($expires)
{
$this->expires = $expires;
return $this;
}
/**
* @return array
*/
public function getArgs(): array
{
return $this->args;
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace frostealth\yii2\aws\s3\commands;
use frostealth\yii2\aws\s3\base\commands\ExecutableCommand;
use frostealth\yii2\aws\s3\interfaces\commands\HasBucket;
/**
* Class GetUrlCommand
*
* @method string execute()
*
* @package frostealth\yii2\aws\s3\commands
*/
class GetUrlCommand extends ExecutableCommand implements HasBucket
{
/** @var string */
protected $bucket;
/** @var string */
protected $filename;
/**
* @return string
*/
public function getBucket(): string
{
return $this->bucket;
}
/**
* @param string $bucket
*
* @return $this
*/
public function setBucket(string $bucket)
{
$this->bucket = $bucket;
return $this;
}
/**
* @return string
*/
public function getFilename(): string
{
return $this->filename;
}
/**
* @param string $filename
*
* @return $this
*/
public function setFilename(string $filename)
{
$this->filename = $filename;
return $this;
}
}

185
src/commands/PutCommand.php Normal file
View File

@@ -0,0 +1,185 @@
<?php
namespace frostealth\yii2\aws\s3\commands;
use Aws\ResultInterface;
use frostealth\yii2\aws\s3\base\commands\ExecutableCommand;
use frostealth\yii2\aws\s3\base\commands\traits\Async;
use frostealth\yii2\aws\s3\base\commands\traits\Options;
use frostealth\yii2\aws\s3\interfaces\commands\Asynchronous;
use frostealth\yii2\aws\s3\interfaces\commands\HasAcl;
use frostealth\yii2\aws\s3\interfaces\commands\HasBucket;
use frostealth\yii2\aws\s3\interfaces\commands\PlainCommand;
use GuzzleHttp\Promise\PromiseInterface;
/**
* Class PutCommand
*
* @method ResultInterface|PromiseInterface execute()
*
* @package frostealth\yii2\aws\s3\commands
*/
class PutCommand extends ExecutableCommand implements PlainCommand, HasBucket, HasAcl, Asynchronous
{
use Async;
use Options;
/** @var array */
protected $args = [];
/**
* @return string
*/
public function getBucket(): string
{
return $this->args['Bucket'] ?? '';
}
/**
* @param string $bucket
*
* @return $this
*/
public function setBucket(string $bucket)
{
$this->args['Bucket'] = $bucket;
return $this;
}
/**
* @return string
*/
public function getFilename(): string
{
return $this->args['Key'] ?? '';
}
/**
* @param string $filename
*
* @return $this
*/
public function setFilename(string $filename)
{
$this->args['Key'] = $filename;
return $this;
}
/**
* @return string
*/
public function getAcl(): string
{
return $this->args['ACL'] ?? '';
}
/**
* @param string $acl
*
* @return $this
*/
public function setAcl(string $acl)
{
$this->args['ACL'] = $acl;
return $this;
}
/**
* @return mixed
*/
public function getBody()
{
return $this->args['Body'] ?? null;
}
/**
* @param mixed $body
*
* @return $this
*/
public function setBody($body)
{
$this->args['Body'] = $body;
return $this;
}
/**
* @return array
*/
public function getMetadata(): array
{
return $this->args['Metadata'] ?? [];
}
/**
* @param array $metadata
*
* @return $this
*/
public function setMetadata(array $metadata)
{
$this->args['Metadata'] = $metadata;
return $this;
}
/**
* @return string
*/
public function getContentType(): string
{
return $this->args['ContentType'] ?? '';
}
/**
* @param string $contentType
*
* @return $this
*/
public function setContentType(string $contentType)
{
$this->args['ContentType'] = $contentType;
return $this;
}
/**
* @return mixed
*/
public function getExpires()
{
return $this->args['Expires'] ?? null;
}
/**
* @param mixed $expires
*
* @return $this
*/
public function setExpires($expires)
{
$this->args['Expires'] = $expires;
return $this;
}
/**
* @return string
*/
public function getName(): string
{
return 'PutObject';
}
/**
* @return array
*/
public function toArgs(): array
{
return array_replace($this->options, $this->args);
}
}

View File

@@ -0,0 +1,122 @@
<?php
namespace frostealth\yii2\aws\s3\commands;
use Aws\ResultInterface;
use frostealth\yii2\aws\s3\base\commands\ExecutableCommand;
use frostealth\yii2\aws\s3\base\commands\traits\Async;
use frostealth\yii2\aws\s3\interfaces\commands\Asynchronous;
use frostealth\yii2\aws\s3\interfaces\commands\HasBucket;
use frostealth\yii2\aws\s3\interfaces\commands\PlainCommand;
use GuzzleHttp\Promise\PromiseInterface;
/**
* Class RestoreCommand
*
* @method ResultInterface|PromiseInterface execute()
*
* @package frostealth\yii2\aws\s3\commands
*/
class RestoreCommand extends ExecutableCommand implements PlainCommand, HasBucket, Asynchronous
{
use Async;
/** @var array */
protected $args = [];
/**
* @return string
*/
public function getBucket(): string
{
return $this->args['Bucket'] ?? '';
}
/**
* @param string $bucket
*
* @return $this
*/
public function setBucket(string $bucket)
{
$this->args['Bucket'] = $bucket;
return $this;
}
/**
* @return string
*/
public function getFilename(): string
{
return $this->args['Key'] ?? '';
}
/**
* @param string $filename
*
* @return $this
*/
public function setFilename(string $filename)
{
$this->args['Key'] = $filename;
return $this;
}
/**
* @return int lifetime of the active copy in days
*/
public function getDays(): int
{
return $this->args['Days'] ?? 0;
}
/**
* @param int $days lifetime of the active copy in days
*
* @return $this
*/
public function setDays(int $days)
{
$this->args['Days'] = $days;
return $this;
}
/**
* @return string
*/
public function getVersionId(): string
{
return $this->args['VersionId'] ?? '';
}
/**
* @param string $versionId
*
* @return $this
*/
public function setVersionId(string $versionId)
{
$this->args['VersionId'] = $versionId;
return $this;
}
/**
* @return string
*/
public function getName(): string
{
return 'RestoreObject';
}
/**
* @return array
*/
public function toArgs(): array
{
return $this->args;
}
}

View File

@@ -0,0 +1,198 @@
<?php
namespace frostealth\yii2\aws\s3\commands;
use Aws\ResultInterface;
use frostealth\yii2\aws\s3\base\commands\ExecutableCommand;
use frostealth\yii2\aws\s3\base\commands\traits\Async;
use frostealth\yii2\aws\s3\interfaces\commands\Asynchronous;
use frostealth\yii2\aws\s3\interfaces\commands\HasAcl;
use frostealth\yii2\aws\s3\interfaces\commands\HasBucket;
use GuzzleHttp\Promise\PromiseInterface;
/**
* Class UploadCommand
*
* @method ResultInterface|PromiseInterface execute()
*
* @package frostealth\yii2\aws\s3\commands
*/
class UploadCommand extends ExecutableCommand implements HasBucket, HasAcl, Asynchronous
{
use Async;
/** @var string */
protected $bucket;
/** @var string */
protected $acl;
/** @var mixed */
protected $source;
/** @var string */
protected $filename;
/** @var array */
protected $options = [];
/**
* @return string
*/
public function getBucket(): string
{
return (string)$this->bucket;
}
/**
* @param string $bucket
*
* @return $this
*/
public function setBucket(string $bucket)
{
$this->bucket = $bucket;
return $this;
}
/**
* @return string
*/
public function getAcl(): string
{
return (string)$this->acl;
}
/**
* @param string $acl
*
* @return $this
*/
public function setAcl(string $acl)
{
$this->acl = $acl;
return $this;
}
/**
* @return mixed
*/
public function getSource()
{
return $this->source;
}
/**
* @param mixed $source
*
* @return $this
*/
public function setSource($source)
{
$this->source = $source;
return $this;
}
/**
* @return string
*/
public function getFilename(): string
{
return (string)$this->filename;
}
/**
* @param string $filename
*
* @return $this
*/
public function setFilename(string $filename)
{
$this->filename = $filename;
return $this;
}
/**
* @return int
*/
public function getPartSize(): int
{
return $this->options['part_size'] ?? 0;
}
/**
* @param int $partSize
*
* @return $this
*/
public function setPartSize(int $partSize)
{
$this->options['part_size'] = $partSize;
return $this;
}
/**
* @return int
*/
public function getConcurrency(): int
{
return $this->options['concurrency'] ?? 0;
}
/**
* @param int $concurrency
*
* @return $this
*/
public function setConcurrency(int $concurrency)
{
$this->options['concurrency'] = $concurrency;
return $this;
}
/**
* @return int
*/
public function getMupThreshold(): int
{
return $this->options['mup_threshold'] ?? 0;
}
/**
* @param int $mupThreshold
*
* @return $this
*/
public function setMupThreshold(int $mupThreshold)
{
$this->options['mup_threshold'] = $mupThreshold;
return $this;
}
/**
* @return array
*/
public function getOptions(): array
{
return $this->options;
}
/**
* @param callable $beforeUpload
*
* @return $this
*/
public function beforeUpload(callable $beforeUpload)
{
$this->options['before_upload'] = $beforeUpload;
return $this;
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace frostealth\yii2\aws\s3\handlers;
use frostealth\yii2\aws\s3\base\handlers\Handler;
use frostealth\yii2\aws\s3\commands\ExistCommand;
/**
* Class ExistCommandHandler
*
* @package frostealth\yii2\aws\s3\handlers
*/
final class ExistCommandHandler extends Handler
{
/**
* @param \frostealth\yii2\aws\s3\commands\ExistCommand $command
*
* @return bool
*/
public function handle(ExistCommand $command): bool
{
return $this->s3Client->doesObjectExist(
$command->getBucket(),
$command->getFilename(),
$command->getOptions()
);
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace frostealth\yii2\aws\s3\handlers;
use frostealth\yii2\aws\s3\base\handlers\Handler;
use frostealth\yii2\aws\s3\commands\GetPresignedUrlCommand;
/**
* Class GetPresignedUrlCommandHandler
*
* @package frostealth\yii2\aws\s3\handlers
*/
final class GetPresignedUrlCommandHandler extends Handler
{
/**
* @param \frostealth\yii2\aws\s3\commands\GetPresignedUrlCommand $command
*
* @return string
*/
public function handle(GetPresignedUrlCommand $command): string
{
$awsCommand = $this->s3Client->getCommand('GetObject', $command->getArgs());
$request = $this->s3Client->createPresignedRequest($awsCommand, $command->getExpires());
return (string)$request->getUri();
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace frostealth\yii2\aws\s3\handlers;
use frostealth\yii2\aws\s3\base\handlers\Handler;
use frostealth\yii2\aws\s3\commands\GetUrlCommand;
/**
* Class GetUrlCommandHandler
*
* @package frostealth\yii2\aws\s3\handlers
*/
final class GetUrlCommandHandler extends Handler
{
/**
* @param \frostealth\yii2\aws\s3\commands\GetUrlCommand $command
*
* @return string
*/
public function handle(GetUrlCommand $command): string
{
return $this->s3Client->getObjectUrl($command->getBucket(), $command->getFilename());
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace frostealth\yii2\aws\s3\handlers;
use Aws\CommandInterface as AwsCommand;
use frostealth\yii2\aws\s3\base\handlers\Handler;
use frostealth\yii2\aws\s3\interfaces\commands\Asynchronous;
use frostealth\yii2\aws\s3\interfaces\commands\PlainCommand;
/**
* Class PlainCommandHandler
*
* @package frostealth\yii2\aws\s3\handlers
*/
final class PlainCommandHandler extends Handler
{
/**
* @param \frostealth\yii2\aws\s3\interfaces\commands\PlainCommand $command
*
* @return \Aws\ResultInterface|\GuzzleHttp\Promise\PromiseInterface
*/
public function handle(PlainCommand $command)
{
$awsCommand = $this->toAwsCommand($command);
/** @var \GuzzleHttp\Promise\PromiseInterface $promise */
$promise = $this->s3Client->executeAsync($awsCommand);
return $this->commandIsAsync($command) ? $promise : $promise->wait();
}
/**
* @param \frostealth\yii2\aws\s3\interfaces\commands\PlainCommand $command
*
* @return bool
*/
protected function commandIsAsync(PlainCommand $command): bool
{
return $command instanceof Asynchronous && $command->isAsync();
}
/**
* @param \frostealth\yii2\aws\s3\interfaces\commands\PlainCommand $command
*
* @return \Aws\CommandInterface
*/
protected function toAwsCommand(PlainCommand $command): AwsCommand
{
$args = array_filter($command->toArgs());
return $this->s3Client->getCommand($command->getName(), $args);
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace frostealth\yii2\aws\s3\handlers;
use frostealth\yii2\aws\s3\commands\UploadCommand;
use frostealth\yii2\aws\s3\base\handlers\Handler;
use GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface;
/**
* Class UploadCommandHandler
*
* @package frostealth\yii2\aws\s3\handlers
*/
final class UploadCommandHandler extends Handler
{
/**
* @param \frostealth\yii2\aws\s3\commands\UploadCommand $command
*
* @return \Aws\ResultInterface|\GuzzleHttp\Promise\PromiseInterface
*/
public function handle(UploadCommand $command)
{
$source = $this->toStream($command->getSource());
$options = array_filter($command->getOptions());
$promise = $this->s3Client->uploadAsync(
$command->getBucket(),
$command->getFilename(),
$source,
$command->getAcl(),
$options
);
return $command->isAsync() ? $promise : $promise->wait();
}
/**
* Create a new stream based on the input type.
*
* @param resource|string|StreamInterface $source path to a local file, resource or stream
*
* @return StreamInterface
*/
protected function toStream($source): StreamInterface
{
if (is_string($source)) {
$source = Psr7\try_fopen($source, 'r+');
}
return Psr7\stream_for($source);
}
}

20
src/interfaces/Bus.php Normal file
View File

@@ -0,0 +1,20 @@
<?php
namespace frostealth\yii2\aws\s3\interfaces;
use frostealth\yii2\aws\s3\interfaces\commands\Command;
/**
* Interface Bus
*
* @package frostealth\yii2\aws\s3\interfaces
*/
interface Bus
{
/**
* @param \frostealth\yii2\aws\s3\interfaces\commands\Command $command
*
* @return mixed
*/
public function execute(Command $command);
}

View File

@@ -0,0 +1,20 @@
<?php
namespace frostealth\yii2\aws\s3\interfaces;
use frostealth\yii2\aws\s3\interfaces\commands\Command;
/**
* Interface CommandBuilder
*
* @package frostealth\yii2\aws\s3\interfaces
*/
interface CommandBuilder
{
/**
* @param string $commandClass
*
* @return \frostealth\yii2\aws\s3\interfaces\commands\Command
*/
public function build(string $commandClass): Command;
}

View File

@@ -0,0 +1,27 @@
<?php
namespace frostealth\yii2\aws\s3\interfaces;
use frostealth\yii2\aws\s3\interfaces\commands\Command;
use frostealth\yii2\aws\s3\interfaces\handlers\Handler;
/**
* Interface HandlerResolver
*
* @package frostealth\yii2\aws\s3\interfaces
*/
interface HandlerResolver
{
/**
* @param \frostealth\yii2\aws\s3\interfaces\commands\Command $command
*
* @return \frostealth\yii2\aws\s3\interfaces\handlers\Handler
*/
public function resolve(Command $command): Handler;
/**
* @param string $commandClass
* @param mixed $handler
*/
public function bindHandler(string $commandClass, $handler);
}

View File

@@ -0,0 +1,27 @@
<?php
namespace frostealth\yii2\aws\s3\interfaces;
use frostealth\yii2\aws\s3\interfaces\commands\Command;
/**
* Interface Service
*
* @package frostealth\yii2\aws\s3\interfaces
*/
interface Service
{
/**
* @param \frostealth\yii2\aws\s3\interfaces\commands\Command $command
*
* @return mixed
*/
public function execute(Command $command);
/**
* @param string $commandClass
*
* @return \frostealth\yii2\aws\s3\interfaces\commands\Command
*/
public function create(string $commandClass): Command;
}

View File

@@ -0,0 +1,21 @@
<?php
namespace frostealth\yii2\aws\s3\interfaces\commands;
/**
* Interface Asynchronous
*
* @package frostealth\yii2\aws\s3\interfaces\commands
*/
interface Asynchronous
{
/**
* @param bool $async
*/
public function async(bool $async = true);
/**
* @return bool
*/
public function isAsync(): bool;
}

View File

@@ -0,0 +1,12 @@
<?php
namespace frostealth\yii2\aws\s3\interfaces\commands;
/**
* Interface Command
*
* @package frostealth\yii2\aws\s3\interfaces\commands
*/
interface Command
{
}

View File

@@ -0,0 +1,16 @@
<?php
namespace frostealth\yii2\aws\s3\interfaces\commands;
/**
* Interface ExecutableCommand
*
* @package frostealth\yii2\aws\s3\interfaces\commands
*/
interface ExecutableCommand extends Command
{
/**
* @return mixed
*/
public function execute();
}

View File

@@ -0,0 +1,16 @@
<?php
namespace frostealth\yii2\aws\s3\interfaces\commands;
/**
* Interface HasAcl
*
* @package frostealth\yii2\aws\s3\interfaces\commands
*/
interface HasAcl
{
/**
* @param string $acl
*/
public function setAcl(string $acl);
}

View File

@@ -0,0 +1,16 @@
<?php
namespace frostealth\yii2\aws\s3\interfaces\commands;
/**
* Interface HasBucket
*
* @package frostealth\yii2\aws\s3\interfaces\commands
*/
interface HasBucket
{
/**
* @param string $bucket
*/
public function setBucket(string $bucket);
}

View File

@@ -0,0 +1,21 @@
<?php
namespace frostealth\yii2\aws\s3\interfaces\commands;
/**
* Interface PlainCommand
*
* @package frostealth\yii2\aws\s3\interfaces\commands
*/
interface PlainCommand extends Command
{
/**
* @return string
*/
public function getName(): string;
/**
* @return array
*/
public function toArgs(): array;
}

View File

@@ -0,0 +1,12 @@
<?php
namespace frostealth\yii2\aws\s3\interfaces\handlers;
/**
* Interface Handler
*
* @package frostealth\yii2\aws\s3\interfaces\handlers
*/
interface Handler
{
}