This commit is contained in:
Maxime Renou 2019-02-21 13:20:53 +01:00
parent dc81eea51d
commit e29cf49424
4 changed files with 66 additions and 11 deletions

View File

@ -27,6 +27,7 @@ class S3Storage implements StorageAdaptor
$this->config = $config; $this->config = $config;
$this->bucket = $config['bucket']; $this->bucket = $config['bucket'];
$this->bucket_url = $config['bucket_url'];
$this->client = new S3Client([ $this->client = new S3Client([
'version' => isset($config['version']) ? $config['version'] : 'latest', 'version' => isset($config['version']) ? $config['version'] : 'latest',
@ -50,6 +51,7 @@ class S3Storage implements StorageAdaptor
return ( return (
isset($config['type']) && isset($config['type']) &&
isset($config['bucket']) && isset($config['bucket']) &&
isset($config['bucket_url']) &&
isset($config['region']) && isset($config['region']) &&
isset($config['endpoint']) && isset($config['endpoint']) &&
isset($config['credentials']) && isset($config['credentials']) &&
@ -86,7 +88,7 @@ class S3Storage implements StorageAdaptor
*/ */
public function url ($target_path) public function url ($target_path)
{ {
return rtrim($this->config['endpoint'], '/').'/'.$this->getPrefix().ltrim($target_path, '/'); return rtrim($this->bucket_url, '/').'/'.$this->getPrefix().ltrim($target_path, '/');
} }
/** /**

View File

@ -15,17 +15,17 @@ class Storage implements ORM\Annotation
public $name; public $name;
/** /**
* @var string|null * @var mixed
*/ */
public $prefix = null; public $prefix = null;
/** /**
* @var string|null * @var mixed
*/ */
public $mode = null; public $mode = null;
/** /**
* @var string|null * @var mixed
*/ */
public $mime = null; public $mime = null;
} }

View File

@ -22,6 +22,7 @@ class Configuration implements ConfigurationInterface
->children() ->children()
->scalarNode('type')->isRequired()->cannotBeEmpty()->end() ->scalarNode('type')->isRequired()->cannotBeEmpty()->end()
->scalarNode('bucket')->end() ->scalarNode('bucket')->end()
->scalarNode('bucket_url')->end()
->scalarNode('region')->end() ->scalarNode('region')->end()
->scalarNode('endpoint')->end() ->scalarNode('endpoint')->end()
->arrayNode('credentials') ->arrayNode('credentials')

View File

@ -41,7 +41,7 @@ class Storage
return (null); return (null);
} }
public function store($entity, $attribute, $file) protected function getStorageAnnotation($entity, $attribute)
{ {
$reflection = new \ReflectionProperty($entity, $attribute); $reflection = new \ReflectionProperty($entity, $attribute);
$reader = new AnnotationReader(); $reader = new AnnotationReader();
@ -61,17 +61,65 @@ class Storage
throw new MissingStorageAnnotation("Missing Storage annotation for $attribute in ".get_class($entity)); throw new MissingStorageAnnotation("Missing Storage annotation for $attribute in ".get_class($entity));
} }
return $storage_annotation;
}
public function getStorageFor($entity, $attribute)
{
$annotation = $this->getStorageAnnotation($entity, $attribute);
return $annotation->name;
}
public function url($entity, $attribute)
{
$annotation = $this->getStorageAnnotation($entity, $attribute);
$storage = $this->get($annotation->name);
$prefix = is_null($annotation->prefix) || empty($annotation->prefix) ? '' : trim($annotation->prefix, '/').'/';
$camel = ucfirst(Container::camelize($attribute));
return $storage->url("$prefix{$entity->{"get".$camel}()}");
}
public function delete($entity, $attribute)
{
$annotation = $this->getStorageAnnotation($entity, $attribute);
$storage = $this->get($annotation->name);
$prefix = is_null($annotation->prefix) || empty($annotation->prefix) ? '' : trim($annotation->prefix, '/').'/';
$camel = ucfirst(Container::camelize($attribute));
return $storage->delete("$prefix{$entity->{"get".$camel}()}");
}
public function retrieve($entity, $attribute, $local_path)
{
$annotation = $this->getStorageAnnotation($entity, $attribute);
$storage = $this->get($annotation->name);
$prefix = is_null($annotation->prefix) || empty($annotation->prefix) ? '' : trim($annotation->prefix, '/').'/';
$camel = ucfirst(Container::camelize($attribute));
return $storage->retrieve("$prefix{$entity->{"get".$camel}()}", $local_path);
}
public function stream($entity, $attribute, $target_stream)
{
$annotation = $this->getStorageAnnotation($entity, $attribute);
$storage = $this->get($annotation->name);
$prefix = is_null($annotation->prefix) || empty($annotation->prefix) ? '' : trim($annotation->prefix, '/').'/';
$camel = ucfirst(Container::camelize($attribute));
return $storage->stream("$prefix{$entity->{"get".$camel}()}", $target_stream);
}
public function store($entity, $attribute, $file)
{
$storage_annotation = $this->getStorageAnnotation($entity, $attribute);
$file_hash = hash('sha256', time().$attribute.uniqid()); $file_hash = hash('sha256', time().$attribute.uniqid());
$storage = $this->get($storage_annotation->name); $storage = $this->get($storage_annotation->name);
if (is_null($storage_annotation)) if (is_null($storage))
{ {
throw new UnknownStorage("Unknown storage for $attribute in ".get_class($entity)); throw new UnknownStorage("Unknown storage {$storage_annotation->name} for $attribute in ".get_class($entity));
} }
$prefix = is_null($storage_annotation->prefix) || empty($storage_annotation->prefix) ? '' : trim($storage_annotation->prefix, '/').'/'; $prefix = is_null($storage_annotation->prefix) || empty($storage_annotation->prefix) ? '' : trim($storage_annotation->prefix, '/').'/';
$mode = $storage->mode($storage_annotation->mode); $mode = $storage->mode($storage_annotation->mode);
$camel = ucfirst(Container::camelize($attribute));
if ($file instanceof UploadedFile) { if ($file instanceof UploadedFile) {
if (!is_null($storage_annotation->mime)) { if (!is_null($storage_annotation->mime)) {
@ -82,21 +130,25 @@ class Storage
else { else {
$valid = strtolower($storage_annotation->mime) == explode('/', $file->getMimeType())[0]; $valid = strtolower($storage_annotation->mime) == explode('/', $file->getMimeType())[0];
} }
if (!$valid) { if (!$valid) {
throw new MimeTypeException("Invalid mime type"); throw new MimeTypeException("Invalid mime type");
} }
} }
$storage->store($file->getRealPath(), "$prefix$file_hash", $mode); $storage->store($file->getRealPath(), "$prefix$file_hash", $mode);
$previous_file_hash = $entity->{"get$camel"}();
if (!is_null($previous_file_hash) && !empty($previous_file_hash)) {
$storage->delete("$prefix$previous_file_hash");
}
} }
elseif (is_string($file) && file_exists($file)) { elseif (is_string($file) && file_exists($file)) {
$storage->store($file, "$prefix$file_hash", $mode); $storage->store($file, "$prefix$file_hash", $mode);
} }
else { else {
throw new InvalidFileException("Invalid file arguement"); throw new InvalidFileException("Invalid file argument");
} }
$camel = lcfirst(Container::camelize($attribute));
$entity->{"set$camel"}($file_hash); $entity->{"set$camel"}($file_hash);
return $file_hash; return $file_hash;