Last active
December 11, 2022 14:51
Laravel StorageProxy class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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