Awesome features (you'll see)

This commit is contained in:
Maxime Renou 2019-02-21 12:28:32 +01:00
parent 62f60374ea
commit dc81eea51d
10 changed files with 164 additions and 3 deletions

View File

@ -3,6 +3,7 @@
namespace Bluesquare\StorageBundle\Adaptors; namespace Bluesquare\StorageBundle\Adaptors;
use Aws\S3\S3Client; use Aws\S3\S3Client;
use Bluesquare\StorageBundle\Exceptions\InvalidStorageConfiguration;
use Symfony\Component\Config\Definition\Exception\Exception; use Symfony\Component\Config\Definition\Exception\Exception;
/** /**
@ -10,7 +11,7 @@ use Symfony\Component\Config\Definition\Exception\Exception;
* Usage: $storage = new S3Storage('my_storage_name', $config); * Usage: $storage = new S3Storage('my_storage_name', $config);
* @author Maxime Renou * @author Maxime Renou
*/ */
class S3Storage class S3Storage implements StorageAdaptor
{ {
const MODE_PRIVATE = 'private'; const MODE_PRIVATE = 'private';
const MODE_PUBLIC = 'public-read'; const MODE_PUBLIC = 'public-read';
@ -22,7 +23,7 @@ class S3Storage
public function __construct ($storage_name, $config) public function __construct ($storage_name, $config)
{ {
if (!($this->configIsNormed($config))) if (!($this->configIsNormed($config)))
throw new Exception("Error from config file :("); throw new InvalidStorageConfiguration("Invalid $storage_name storage configuration");
$this->config = $config; $this->config = $config;
$this->bucket = $config['bucket']; $this->bucket = $config['bucket'];
@ -38,6 +39,12 @@ class S3Storage
]); ]);
} }
public function mode($name)
{
if ($name == 'public') return self::MODE_PUBLIC;
return self::MODE_PRIVATE;
}
private function configIsNormed($config) private function configIsNormed($config)
{ {
return ( return (

View File

@ -0,0 +1,13 @@
<?php
namespace Bluesquare\StorageBundle\Adaptors;
interface StorageAdaptor
{
public function index();
public function mode($name);
public function store($source_path, $target_path);
public function retrieve($distant_path, $local_path);
public function stream($distant_path, $target_stream);
public function delete($distant_path);
}

View File

@ -0,0 +1,31 @@
<?php
namespace Bluesquare\StorageBundle\Annotations;
use Doctrine\ORM\Mapping as ORM;
/**
* @Annotation
*/
class Storage implements ORM\Annotation
{
/**
* @var string
*/
public $name;
/**
* @var string|null
*/
public $prefix = null;
/**
* @var string|null
*/
public $mode = null;
/**
* @var string|null
*/
public $mime = null;
}

View File

@ -0,0 +1,8 @@
<?php
namespace Bluesquare\StorageBundle\Exceptions;
class InvalidFileException extends \Exception
{
}

View File

@ -0,0 +1,8 @@
<?php
namespace Bluesquare\StorageBundle\Exceptions;
class InvalidStorageConfiguration extends \Exception
{
}

View File

@ -0,0 +1,8 @@
<?php
namespace Bluesquare\StorageBundle\Exceptions;
class MimeTypeException extends \Exception
{
}

View File

@ -0,0 +1,8 @@
<?php
namespace Bluesquare\StorageBundle\Exceptions;
class MissingStorageAnnotation extends \Exception
{
}

View File

@ -0,0 +1,8 @@
<?php
namespace Bluesquare\StorageBundle\Exceptions;
class UnknownStorage extends \Exception
{
}

View File

@ -4,6 +4,14 @@ namespace Bluesquare\StorageBundle;
use Aws\S3\S3Client; use Aws\S3\S3Client;
use Bluesquare\StorageBundle\Adaptors\S3Storage; use Bluesquare\StorageBundle\Adaptors\S3Storage;
use Bluesquare\StorageBundle\Exceptions\InvalidFileException;
use Bluesquare\StorageBundle\Exceptions\MimeTypeException;
use Bluesquare\StorageBundle\Exceptions\MissingStorageAnnotation;
use Bluesquare\StorageBundle\Exceptions\UnknownStorage;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Bluesquare\StorageBundle\Annotations\Storage as StorageAnnotation;
use Symfony\Component\DependencyInjection\Container;
use Doctrine\Common\Annotations\AnnotationReader;
/** /**
* Interface de manipulation des stockages préconfigurés * Interface de manipulation des stockages préconfigurés
@ -32,4 +40,65 @@ class Storage
return (null); return (null);
} }
public function store($entity, $attribute, $file)
{
$reflection = new \ReflectionProperty($entity, $attribute);
$reader = new AnnotationReader();
$annotations = $reader->getPropertyAnnotations($reflection);
$storage_annotation = null;
foreach ($annotations as $annotation)
{
if ($annotation instanceof StorageAnnotation) {
$storage_annotation = $annotation;
}
}
if (is_null($storage_annotation))
{
throw new MissingStorageAnnotation("Missing Storage annotation for $attribute in ".get_class($entity));
}
$file_hash = hash('sha256', time().$attribute.uniqid());
$storage = $this->get($storage_annotation->name);
if (is_null($storage_annotation))
{
throw new UnknownStorage("Unknown storage 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);
if ($file instanceof UploadedFile) {
if (!is_null($storage_annotation->mime)) {
$valid = true;
if (count(explode('/', $storage_annotation->mime)) > 1) {
$valid = strtolower($storage_annotation->mime) == $file->getMimeType();
}
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);
}
elseif (is_string($file) && file_exists($file)) {
$storage->store($file, "$prefix$file_hash", $mode);
}
else {
throw new InvalidFileException("Invalid file arguement");
}
$camel = lcfirst(Container::camelize($attribute));
$entity->{"set$camel"}($file_hash);
return $file_hash;
}
} }

View File

@ -12,7 +12,8 @@
"type": "symfony-bundle", "type": "symfony-bundle",
"require": { "require": {
"php": ">=7.1", "php": ">=7.1",
"aws/aws-sdk-php": "^3.81" "aws/aws-sdk-php": "^3.81",
"doctrine/event-manager": "*"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {