diff --git a/StorageBundle/Adaptors/S3Storage.php b/StorageBundle/Adaptors/S3Storage.php index 1ea29a0..69f89f4 100644 --- a/StorageBundle/Adaptors/S3Storage.php +++ b/StorageBundle/Adaptors/S3Storage.php @@ -27,6 +27,7 @@ class S3Storage implements StorageAdaptor $this->config = $config; $this->bucket = $config['bucket']; + $this->bucket_url = $config['bucket_url']; $this->client = new S3Client([ 'version' => isset($config['version']) ? $config['version'] : 'latest', @@ -50,6 +51,7 @@ class S3Storage implements StorageAdaptor return ( isset($config['type']) && isset($config['bucket']) && + isset($config['bucket_url']) && isset($config['region']) && isset($config['endpoint']) && isset($config['credentials']) && @@ -86,7 +88,7 @@ class S3Storage implements StorageAdaptor */ 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, '/'); } /** diff --git a/StorageBundle/Annotations/Storage.php b/StorageBundle/Annotations/Storage.php index f376b16..294ad8c 100644 --- a/StorageBundle/Annotations/Storage.php +++ b/StorageBundle/Annotations/Storage.php @@ -15,17 +15,17 @@ class Storage implements ORM\Annotation public $name; /** - * @var string|null + * @var mixed */ public $prefix = null; /** - * @var string|null + * @var mixed */ public $mode = null; /** - * @var string|null + * @var mixed */ public $mime = null; } diff --git a/StorageBundle/DependencyInjection/Configuration.php b/StorageBundle/DependencyInjection/Configuration.php index 0359ba9..caad062 100644 --- a/StorageBundle/DependencyInjection/Configuration.php +++ b/StorageBundle/DependencyInjection/Configuration.php @@ -22,6 +22,7 @@ class Configuration implements ConfigurationInterface ->children() ->scalarNode('type')->isRequired()->cannotBeEmpty()->end() ->scalarNode('bucket')->end() + ->scalarNode('bucket_url')->end() ->scalarNode('region')->end() ->scalarNode('endpoint')->end() ->arrayNode('credentials') diff --git a/StorageBundle/Storage.php b/StorageBundle/Storage.php index 060dc30..e6223e3 100644 --- a/StorageBundle/Storage.php +++ b/StorageBundle/Storage.php @@ -41,7 +41,7 @@ class Storage return (null); } - public function store($entity, $attribute, $file) + protected function getStorageAnnotation($entity, $attribute) { $reflection = new \ReflectionProperty($entity, $attribute); $reader = new AnnotationReader(); @@ -61,17 +61,65 @@ class Storage 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()); $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, '/').'/'; - $mode = $storage->mode($storage_annotation->mode); + $camel = ucfirst(Container::camelize($attribute)); if ($file instanceof UploadedFile) { if (!is_null($storage_annotation->mime)) { @@ -82,21 +130,25 @@ class Storage else { $valid = strtolower($storage_annotation->mime) == explode('/', $file->getMimeType())[0]; } + if (!$valid) { throw new MimeTypeException("Invalid mime type"); } } + $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)) { $storage->store($file, "$prefix$file_hash", $mode); } else { - throw new InvalidFileException("Invalid file arguement"); + throw new InvalidFileException("Invalid file argument"); } - $camel = lcfirst(Container::camelize($attribute)); - $entity->{"set$camel"}($file_hash); return $file_hash;