Skip to content

Commit

Permalink
Abstract Storages
Browse files Browse the repository at this point in the history
  • Loading branch information
Remg committed May 27, 2022
1 parent 38e39f5 commit c2f8bcd
Show file tree
Hide file tree
Showing 10 changed files with 588 additions and 0 deletions.
2 changes: 2 additions & 0 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ services:
$dynamicLinksHost: '%env(DYNAMIC_LINKS_HOST)%'
$jemengageAppPackageId: '%env(JEMENGAGE_APP_PACKAGE_ID)%'
$invalidEmailHashKey: '%env(INVALID_EMAIL_HASH_KEY)%'
$publicStorage: '@app.storage.public'
$privateStorage: '@app.strage.private'

_instanceof:
App\Adherent\Unregistration\Handlers\UnregistrationAdherentHandlerInterface:
Expand Down
16 changes: 16 additions & 0 deletions config/services_dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,19 @@ services:

kreait_firebase.jemarche_app.dynamic_links: '@Tests\App\Test\Firebase\DummyDynamicLinks'
kreait_firebase.jemarche_app.messaging: '@Tests\App\Test\Firebase\DummyMessaging'

app.storage.public:
class: 'App\Storage\Storage'
arguments:
- !service
factory: 'App\Storage\AdapterFactory::createLocal'
arguments:
- '%kernel.project_dir%/app/storage/public'

app.storage.private:
class: 'App\Storage\Storage'
arguments:
- !service
factory: 'App\Storage\AdapterFactory::createLocal'
arguments:
- '%kernel.project_dir%/app/storage/private'
27 changes: 27 additions & 0 deletions src/Storage/AdapterFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace App\Storage;

use Google\Cloud\Storage\StorageClient;
use League\Flysystem\Adapter\Local;
use League\Flysystem\Cached\CachedAdapter;
use League\Flysystem\Cached\Storage\Memory;
use Superbalist\Flysystem\GoogleStorage\GoogleStorageAdapter;

class AdapterFactory
{
public static function createLocal(string $localPath): Local
{
return new Local($localPath);
}

public static function createGoogleStorage(string $gcloudBucket, string $pathPrefix = null): CachedAdapter
{
$storage = new StorageClient();

return new CachedAdapter(
new GoogleStorageAdapter($storage, $storage->bucket($gcloudBucket), $pathPrefix),
new Memory(),
);
}
}
21 changes: 21 additions & 0 deletions src/Storage/DummyService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace App\Storage;

/**
* This service is here so that the injected services
* are not removed from the container after compilation.
*
* To be removed.
*/
class DummyService
{
private StorageInterface $publicStorage;
private StorageInterface $privateStorage;

public function __construct(StorageInterface $publicStorage, StorageInterface $privateStorage)
{
$this->publicStorage = $publicStorage;
$this->privateStorage = $privateStorage;
}
}
9 changes: 9 additions & 0 deletions src/Storage/Exception/FileExistsException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace App\Storage\Exception;

use League\Flysystem\FileExistsException as BaseFileExistsException;

class FileExistsException extends BaseFileExistsException
{
}
9 changes: 9 additions & 0 deletions src/Storage/Exception/FileNotFoundException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace App\Storage\Exception;

use League\Flysystem\FileNotFoundException as BaseFileNotFoundException;

class FileNotFoundException extends BaseFileNotFoundException
{
}
92 changes: 92 additions & 0 deletions src/Storage/Storage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

namespace App\Storage;

use App\Storage\Exception\FileExistsException;
use App\Storage\Exception\FileNotFoundException;
use League\Flysystem\AdapterInterface;
use League\Flysystem\FileExistsException as LeagueFileExistsException;
use League\Flysystem\FileNotFoundException as LeagueFileNotFoundException;
use League\Flysystem\Filesystem;

class Storage implements StorageInterface
{
private Filesystem $filesystem;

public function __construct(AdapterInterface $adapter)
{
$this->filesystem = new Filesystem($adapter);
}

public function has(string $path): bool
{
return $this->filesystem->has($path);
}

public function getMimetype(string $path): string
{
try {
return $this->filesystem->getMimetype($path);
} catch (LeagueFileNotFoundException $exception) {
throw $this->createFileNotFoundException($path);
}
}

public function read(string $path): string
{
try {
return $this->filesystem->read($path);
} catch (LeagueFileNotFoundException $exception) {
throw $this->createFileNotFoundException($path);
}
}

public function readStream(string $path)
{
try {
return $this->filesystem->readStream($path);
} catch (LeagueFileNotFoundException $exception) {
throw $this->createFileNotFoundException($path);
}
}

public function put(string $path, string $contents, array $config = []): bool
{
return $this->filesystem->put($path, $contents, $config);
}

public function copy(string $path, string $newPath): bool
{
try {
return $this->filesystem->copy($path, $newPath);
} catch (LeagueFileNotFoundException $exception) {
throw $this->createFileNotFoundException($path);
} catch (LeagueFileExistsException $exception) {
throw $this->createFileExistsException($newPath);
}
}

public function delete(string $path): bool
{
try {
return $this->filesystem->delete($path);
} catch (LeagueFileNotFoundException $exception) {
throw $this->createFileNotFoundException($path);
}
}

public function listContents(string $directory, bool $recursive = false): array
{
return $this->filesystem->listContents($directory, $recursive);
}

private function createFileNotFoundException(string $path): FileNotFoundException
{
return new FileNotFoundException($path);
}

private function createFileExistsException(string $path): FileExistsException
{
return new FileExistsException($path);
}
}
43 changes: 43 additions & 0 deletions src/Storage/StorageInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace App\Storage;

use App\Storage\Exception\FileExistsException;
use App\Storage\Exception\FileNotFoundException;

interface StorageInterface
{
public function has(string $path): bool;

/**
* @throws FileNotFoundException
*/
public function getMimetype(string $path): string;

/**
* @throws FileNotFoundException Thrown if $path does not exist
*/
public function read(string $path): string;

/**
* @throws FileNotFoundException Thrown if $path does not exist
*
* @return resource
*/
public function readStream(string $path);

public function put(string $path, string $contents, array $config = []): bool;

/**
* @throws FileExistsException Thrown if $newpath exists
* @throws FileNotFoundException Thrown if $path does not exist
*/
public function copy(string $path, string $newpath): bool;

/**
* @throws FileNotFoundException
*/
public function delete(string $path): bool;

public function listContents(string $directory, bool $recursive = false): array;
}
37 changes: 37 additions & 0 deletions tests/Storage/AdapterFactoryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace Tests\App\Storage;

use App\Storage\AdapterFactory;
use League\Flysystem\Adapter\Local;
use League\Flysystem\AdapterInterface;
use League\Flysystem\Cached\CachedAdapter;
use PHPUnit\Framework\TestCase;
use Superbalist\Flysystem\GoogleStorage\GoogleStorageAdapter;

class AdapterFactoryTest extends TestCase
{
public function testCreateLocal(): void
{
$tmp = sys_get_temp_dir().'/storage-local/';

$adapter = AdapterFactory::createLocal($tmp);

self::assertInstanceOf(Local::class, $adapter);
self::assertInstanceOf(AdapterInterface::class, $adapter);
self::assertSame($tmp, $adapter->getPathPrefix());
self::assertDirectoryExists($tmp);

rmdir($tmp);
}

public function testCreateGoogleStorage(): void
{
$adapter = AdapterFactory::createGoogleStorage('foo-bucket', 'path/to/dir');

self::assertInstanceOf(CachedAdapter::class, $adapter);
self::assertInstanceOf(AdapterInterface::class, $adapter);
self::assertInstanceOf(GoogleStorageAdapter::class, $adapter->getAdapter());
self::assertSame('path/to/dir/', $adapter->getPathPrefix());
}
}
Loading

0 comments on commit c2f8bcd

Please sign in to comment.