Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/services/drivers/google_cloud_storage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ services:
bind:
$storageClient: '@sfs_media.storage.google_cloud.storage_client'
$bucket: '%sfs_media.storage.google_cloud_storage.bucket%'
$publicBaseUrl: '%sfs_media.storage.google_cloud_storage.public_base_url%'

sfs_media.storage.google_cloud.storage_client:
class: Google\Cloud\Storage\StorageClient
Expand Down
3 changes: 2 additions & 1 deletion src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Configuration implements ConfigurationInterface
{
private const HELP_AVIF = <<<HELP
Avif format is not supported by your PHP environment. Please add support for it.

Depending on your system, add the following packages:

$ apt install libavif-dev # Debian/Ubuntu
Expand Down Expand Up @@ -107,6 +107,7 @@ public function getConfigTreeBuilder(): TreeBuilder
->arrayNode('google_cloud_storage')
->children()
->scalarNode('bucket')->end()
->scalarNode('public_base_url')->defaultNull()->end()
->end()
->end()

Expand Down
1 change: 1 addition & 0 deletions src/DependencyInjection/SfsMediaExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public function load(array $configs, ContainerBuilder $container): void

if ('google_cloud_storage' === $config['driver']) {
$container->setParameter('sfs_media.storage.google_cloud_storage.bucket', $config['google_cloud_storage']['bucket']);
$container->setParameter('sfs_media.storage.google_cloud_storage.public_base_url', $config['google_cloud_storage']['public_base_url']);
$loader->load('drivers/google_cloud_storage.yaml');
}

Expand Down
16 changes: 1 addition & 15 deletions src/Model/MediaVersion.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,21 +101,7 @@ public function setUrl(?string $url): void

public function getPublicUrl(): ?string
{
$url = $this->getUrl();

if (!$url) {
return null;
}

if (str_starts_with($url, 'gs://')) {
return 'https://storage.googleapis.com/'.substr($url, 5);
}

if (str_starts_with($url, 'sfs-media-filesystem://')) {
return '/media/'.substr($url, 23);
}

return $url;
return null; // todo if value in database render it (add new field)
}

public function getWidth(): ?int
Expand Down
34 changes: 22 additions & 12 deletions src/Storage/GoogleCloudStorageDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,8 @@

class GoogleCloudStorageDriver implements StorageDriverInterface
{
protected StorageClient $storageClient;

protected string $bucket;

public function __construct(StorageClient $storageClient, string $bucket)
public function __construct(protected StorageClient $storageClient, protected string $bucket, protected ?string $publicBaseUrl = null)
{
$this->storageClient = $storageClient;
$this->bucket = $bucket;
}

public function store(File $file, string $destName): string
Expand All @@ -29,7 +23,7 @@ public function store(File $file, string $destName): string

public function remove(string $fileName): void
{
if ('gs://' !== substr($fileName, 0, 5)) {
if (!str_starts_with($fileName, 'gs://')) {
return;
}

Expand All @@ -45,7 +39,7 @@ public function remove(string $fileName): void

public function download(string $fileName, string $destPath): void
{
if ('gs://' !== substr($fileName, 0, 5)) {
if (!str_starts_with($fileName, 'gs://')) {
return;
}

Expand All @@ -61,10 +55,26 @@ public function download(string $fileName, string $destPath): void

public function url(string $fileName): string
{
if (str_starts_with($fileName, 'gs://')) {
return 'https://storage.googleapis.com/'.substr($fileName, 5);
if (!str_starts_with($fileName, 'gs://')) {
return $fileName;
}

$fileName = substr($fileName, 5);
$parts = explode('/', $fileName, 2);

$bucket = $parts[0];
$filePath = $parts[1] ?? null;

$publicBaseUrl = null !== $this->publicBaseUrl ? trim($this->publicBaseUrl) : null;
if ($filePath && '' === $publicBaseUrl) {
return "/$filePath";
}

if ($filePath && null !== $publicBaseUrl && 'null' !== strtolower($publicBaseUrl)) {
$publicBaseUrl = rtrim($publicBaseUrl, '/');
return "$publicBaseUrl/$filePath";
}

return $fileName;
return "https://storage.googleapis.com/$bucket".($filePath ? "/$filePath" : '');
}
}
19 changes: 19 additions & 0 deletions tests/Unit/DependencyInjection/ConfigurationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,23 @@ public function testAdvancedConfig()
$config['types'] = Configuration::fixConfigTypes($config['types'] ?? null);
$this->assertEquals($expected, $config);
}

public function testGoogleCloudStorageConfigWithoutPublicBaseUrl()
{
$configs = [
'sfs_media' => [
'google_cloud_storage' => [
'bucket' => 'media-bucket',
],
],
];

$processor = new Processor();
$configuration = new Configuration();
$config = $processor->processConfiguration($configuration, $configs);

$this->assertSame('google_cloud_storage', $config['driver']);
$this->assertSame('media-bucket', $config['google_cloud_storage']['bucket']);
$this->assertNull($config['google_cloud_storage']['public_base_url']);
}
}
65 changes: 65 additions & 0 deletions tests/Unit/Storage/GoogleCloudStorageDriverTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

namespace Softspring\MediaBundle\Tests\Unit\Storage;

use Google\Cloud\Storage\StorageClient;
use PHPUnit\Framework\TestCase;
use Softspring\MediaBundle\Storage\GoogleCloudStorageDriver;

class GoogleCloudStorageDriverTest extends TestCase
{
/**
* @dataProvider urlProvider
*/
public function testUrl(string $storedUrl, ?string $publicBaseUrl, string $expectedUrl): void
{
$driver = new GoogleCloudStorageDriver($this->createMock(StorageClient::class), 'media-bucket', $publicBaseUrl);

$this->assertSame($expectedUrl, $driver->url($storedUrl));
}

public function urlProvider(): iterable
{
yield 'non gcs url' => [
'https://example.com/image.jpg',
'https://cdn.example.com/media',
'https://example.com/image.jpg',
];

yield 'gcs url without public base url' => [
'gs://media-bucket/path/to/image.jpg',
null,
'https://storage.googleapis.com/media-bucket/path/to/image.jpg',
];

yield 'gcs url with public base url' => [
'gs://media-bucket/path/to/image.jpg',
'https://cdn.example.com/media',
'https://cdn.example.com/media/path/to/image.jpg',
];

yield 'gcs url with trailing slash in public base url' => [
'gs://media-bucket/path/to/image.jpg',
'https://cdn.example.com/media/',
'https://cdn.example.com/media/path/to/image.jpg',
];

yield 'gcs url with string null public base url' => [
'gs://media-bucket/path/to/image.jpg',
'null',
'https://storage.googleapis.com/media-bucket/path/to/image.jpg',
];

yield 'gcs url with empty public base url' => [
'gs://media-bucket/path/to/image.jpg',
'',
'/path/to/image.jpg',
];

yield 'gcs bucket url without path' => [
'gs://media-bucket',
'https://cdn.example.com/media',
'https://storage.googleapis.com/media-bucket',
];
}
}
Loading