Skip to content

Instantly share code, notes, and snippets.

@erfansahaf
Last active December 11, 2022 14:51
Show Gist options
  • Save erfansahaf/68544076d80baa9939a3300d21e15df9 to your computer and use it in GitHub Desktop.
Save erfansahaf/68544076d80baa9939a3300d21e15df9 to your computer and use it in GitHub Desktop.
Laravel StorageProxy class
<?php
namespace App\Utils;
use Illuminate\Contracts\Filesystem\Filesystem;
use Illuminate\Support\Facades\Storage;
class StorageProxy
{
private $disk;
private $bucket;
private $isS3Storage;
private $bucketDetection = true;
/**
* @param string|null $disk
* @param string|null $bucket
* @return Storage
*/
public static function touch(?string $disk = null, ?string $bucket = null)
{
if (!$disk) {
$disk = config("filesystems.default");
}
return new static ($disk, $bucket);
}
/**
* StorageProxy constructor.
*
* Note: This class is designed to be used for all storage drivers with ability to set S3 bucket name dynamically
*
* @param string $disk
* @param string|null $bucket
*/
public function __construct(string $disk, ?string $bucket = null)
{
$this->disk = $disk;
$this->bucket = $bucket;
$this->isS3Storage = $this->isDriverS3($disk);
}
private function makeStorageObject(string $disk, ?string $bucket = null): Filesystem
{
// Discard changes for non-s3 disks
if (!$this->isS3Storage) {
return Storage::disk($disk);
}
$configuration = config("filesystems.disks.{$disk}");
// If S3 disk has a bucket name
if ($this->isS3Storage && isset($configuration['bucket'])) {
$this->bucket = $configuration['bucket'];
return Storage::disk($disk);
}
return $this->createS3Disk($configuration, $bucket);
}
public function bucketDetection(bool $autoDetect)
{
$this->bucketDetection = $autoDetect;
return $this;
}
public function __call($methodName, $params)
{
$bucket = null;
// Check if the first argument is a path
if ($this->isS3Storage && is_string($params[0])) {
$bucket = $this->bucket ?: $this->extractBucketFromPath($params[0]);
if ($bucket == null) {
throw new \Exception("Couldn't find the bucket name.");
}
$params[0] = $this->removeBucketFromPath($params[0], $bucket);
}
return call_user_func_array([$this->makeStorageObject($this->disk, $bucket), $methodName], $params);
}
private function createS3Disk(array $properties, string $bucket)
{
return Storage::createS3Driver(array_merge($properties, ['bucket' => $bucket]));
}
private function isDriverS3(string $disk)
{
return config("filesystems.disks.{$disk}.driver") == "s3";
}
private function extractBucketFromPath(string $path)
{
$parts = explode("/", $path);
if (count($parts) > 1 && $this->bucketDetection) {
return $parts[0];
}
return null;
}
private function removeBucketFromPath(string $path, string $bucket)
{
return preg_replace("/^($bucket\/)/", "", $path, 1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment