From 785091c9e0b6d74795174a03a38c1894784b5e0e Mon Sep 17 00:00:00 2001 From: Troels Johnsen Date: Thu, 19 Dec 2019 14:43:02 +0100 Subject: [PATCH 1/3] Make it possible to use optional parameters Using optional parameters it is possible to i.e. save uploaded files to a specific folder. --- README.md | 22 +++++++++++++++++++++- src-php/Adapters/CloudinaryAdapter.php | 16 +++++++++++----- src-php/Fields/CloudinaryAudio.php | 17 +++++++++++++++-- src-php/Fields/CloudinaryFile.php | 22 +++++++++++++++++++--- src-php/Fields/CloudinaryImage.php | 19 +++++++++++++++++-- src-php/Fields/CloudinaryOptions.php | 16 ++++++++++++++++ src-php/Fields/CloudinaryVideo.php | 17 +++++++++++++++-- 7 files changed, 114 insertions(+), 15 deletions(-) create mode 100644 src-php/Fields/CloudinaryOptions.php diff --git a/README.md b/README.md index 12e6cb8..2b93173 100644 --- a/README.md +++ b/README.md @@ -171,4 +171,24 @@ public function fields(Request $request) } ``` -This field sets the disk in use to `Cloudinary` and ensures the media is stored in the database field with the correct file extension. \ No newline at end of file +This field sets the disk in use to `Cloudinary` and ensures the media is stored in the database field with the correct file extension. + +## Configuration + +If you want to use any of the [optional parameters](https://cloudinary.com/documentation/image_upload_api_reference#optional_parameters) of the Cloudinary Upload API, you can use the `cloudinary` method to send additional parameters. + +The following code uploads images to the images folder instead of the Cloudinary root. + +```php +use Silvanite\NovaFieldCloudinary\Fields\CloudinaryImage; + +public function fields(Request $request) +{ + return [ + ... + CloudinaryImage::make('Image')->cloudinary([ + 'folder' => 'images' + ]), + ] +} +``` diff --git a/src-php/Adapters/CloudinaryAdapter.php b/src-php/Adapters/CloudinaryAdapter.php index 6d4b0c0..1561260 100644 --- a/src-php/Adapters/CloudinaryAdapter.php +++ b/src-php/Adapters/CloudinaryAdapter.php @@ -21,14 +21,20 @@ class CloudinaryAdapter extends CloudinaryBaseAdapter */ public function writeStream($path, $resource, Config $config) { + + $cloudinary_options = $config->get('cloudinary') ?? []; + $path = pathinfo($path)['filename']; - $resource_metadata = stream_get_meta_data($resource); - $uploaded_metadata = Uploader::upload($resource_metadata['uri'], [ + // Create the options object + $options = array_merge([ 'public_id' => $path, - 'resource_type' => 'auto', - ]); - + 'resource_type' => 'auto' + ], $cloudinary_options); + + $resource_metadata = stream_get_meta_data($resource); + $uploaded_metadata = Uploader::upload($resource_metadata['uri'], $options); + return $uploaded_metadata; } diff --git a/src-php/Fields/CloudinaryAudio.php b/src-php/Fields/CloudinaryAudio.php index fe241e5..f42a397 100644 --- a/src-php/Fields/CloudinaryAudio.php +++ b/src-php/Fields/CloudinaryAudio.php @@ -20,14 +20,27 @@ public function __construct($name, $attribute = null, $disk = 'cloudinary', $sto { parent::__construct($name, $attribute, $disk, $storageCallback); - $this->storeAs(function (Request $request) { + $this->store(function(Request $request, $model, $attribute, $requestAttribute){ + + $filename = $request->file($requestAttribute)->store($this->getStorageDir(), [ + 'disk' => $this->getStorageDisk(), + 'cloudinary' => $this->cloudinaryOptions + ]); + + // If a folder is specified we ensure a trailing slash + // If no folder is specified we ensure no beginning slash + $path = array_key_exists('folder',$this->cloudinaryOptions) ? rtrim($this->cloudinaryOptions['folder'], '/') . '/' : ''; + + return $path . $filename; + + })->storeAs(function (Request $request) { $name = $request->{$this->attribute}->getClientOriginalName(); $ext = '.' . $request->{$this->attribute}->getClientOriginalExtension(); return sha1($name . time()) . $ext; })->delete(function (Request $request, $model) { $path = pathinfo($model->{$this->attribute}); - Storage::disk($this->disk)->delete($path['filename']); + Storage::disk($this->disk)->delete($path['dirname'] .'/'. $path['filename']); return $this->columnsThatShouldBeDeleted(); }); } diff --git a/src-php/Fields/CloudinaryFile.php b/src-php/Fields/CloudinaryFile.php index 60ccd82..336a994 100644 --- a/src-php/Fields/CloudinaryFile.php +++ b/src-php/Fields/CloudinaryFile.php @@ -7,6 +7,9 @@ class CloudinaryFile extends File { + + use CloudinaryOptions; + /** * Create a new field. * @@ -20,14 +23,27 @@ public function __construct($name, $attribute = null, $disk = 'cloudinary', $sto { parent::__construct($name, $attribute, $disk, $storageCallback); - $this->storeAs(function (Request $request) { + $this->store(function(Request $request, $model, $attribute, $requestAttribute){ + + $filename = $request->file($requestAttribute)->store($this->getStorageDir(), [ + 'disk' => $this->getStorageDisk(), + 'cloudinary' => $this->cloudinaryOptions + ]); + + // If a folder is specified we ensure a trailing slash + // If no folder is specified we ensure no beginning slash + $path = array_key_exists('folder',$this->cloudinaryOptions) ? rtrim($this->cloudinaryOptions['folder'], '/') . '/' : ''; + + return $path . $filename; + + })->storeAs(function (Request $request) { $name = $request->{$this->attribute}->getClientOriginalName(); $ext = '.' . $request->{$this->attribute}->getClientOriginalExtension(); return sha1($name . time()) . $ext; - })>delete(function (Request $request, $model) { + })->delete(function (Request $request, $model) { $path = pathinfo($model->{$this->attribute}); - Storage::disk($this->disk)->delete($path['filename']); + Storage::disk($this->disk)->delete($path['dirname'] .'/'. $path['filename']); return $this->columnsThatShouldBeDeleted(); }); } diff --git a/src-php/Fields/CloudinaryImage.php b/src-php/Fields/CloudinaryImage.php index fa4aad1..c14164e 100644 --- a/src-php/Fields/CloudinaryImage.php +++ b/src-php/Fields/CloudinaryImage.php @@ -8,6 +8,8 @@ class CloudinaryImage extends Image { + use CloudinaryOptions; + /** * Create a new field. * @@ -21,7 +23,20 @@ public function __construct($name, $attribute = null, $disk = 'cloudinary', $sto { parent::__construct($name, $attribute, $disk, $storageCallback); - $this->thumbnail(function () { + $this->store(function(Request $request, $model, $attribute, $requestAttribute){ + + $filename = $request->file($requestAttribute)->store($this->getStorageDir(), [ + 'disk' => $this->getStorageDisk(), + 'cloudinary' => $this->cloudinaryOptions + ]); + + // If a folder is specified we ensure a trailing slash + // If no folder is specified we ensure no beginning slash + $path = array_key_exists('folder',$this->cloudinaryOptions) ? rtrim($this->cloudinaryOptions['folder'], '/') . '/' : ''; + + return $path . $filename; + + })->thumbnail(function () { return $this->value ? cloudinary_image($this->value, [ 'width' => 64, 'height' => 64, @@ -40,7 +55,7 @@ public function __construct($name, $attribute = null, $disk = 'cloudinary', $sto }, $this->value); })->delete(function (Request $request, $model) { $path = pathinfo($model->{$this->attribute}); - Storage::disk($this->disk)->delete($path['filename']); + Storage::disk($this->disk)->delete($path['dirname'] .'/'. $path['filename']); return $this->columnsThatShouldBeDeleted(); }); } diff --git a/src-php/Fields/CloudinaryOptions.php b/src-php/Fields/CloudinaryOptions.php new file mode 100644 index 0000000..4ebf947 --- /dev/null +++ b/src-php/Fields/CloudinaryOptions.php @@ -0,0 +1,16 @@ +cloudinaryOptions = $options; + + return $this; + } + +} diff --git a/src-php/Fields/CloudinaryVideo.php b/src-php/Fields/CloudinaryVideo.php index 2a60c51..f606c72 100644 --- a/src-php/Fields/CloudinaryVideo.php +++ b/src-php/Fields/CloudinaryVideo.php @@ -21,14 +21,27 @@ public function __construct($name, $attribute = null, $disk = 'cloudinary', $sto { parent::__construct($name, $attribute, $disk, $storageCallback); - $this->storeAs(function (Request $request) { + $this->store(function(Request $request, $model, $attribute, $requestAttribute){ + + $filename = $request->file($requestAttribute)->store($this->getStorageDir(), [ + 'disk' => $this->getStorageDisk(), + 'cloudinary' => $this->cloudinaryOptions + ]); + + // If a folder is specified we ensure a trailing slash + // If no folder is specified we ensure no beginning slash + $path = array_key_exists('folder',$this->cloudinaryOptions) ? rtrim($this->cloudinaryOptions['folder'], '/') . '/' : ''; + + return $path . $filename; + + })->storeAs(function (Request $request) { $name = $request->{$this->attribute}->getClientOriginalName(); $ext = '.' . $request->{$this->attribute}->getClientOriginalExtension(); return sha1($name . time()) . $ext; })->delete(function (Request $request, $model) { $path = pathinfo($model->{$this->attribute}); - Storage::disk($this->disk)->delete($path['filename']); + Storage::disk($this->disk)->delete($path['dirname'] .'/'. $path['filename']); return $this->columnsThatShouldBeDeleted(); }); } From ef967ad188eeb41254113c460a45995f830d22b4 Mon Sep 17 00:00:00 2001 From: Troels Johnsen Date: Mon, 1 Mar 2021 20:37:34 +0100 Subject: [PATCH 2/3] Update CloudinaryImage.php Fix download URL of images using folders --- src-php/Fields/CloudinaryImage.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src-php/Fields/CloudinaryImage.php b/src-php/Fields/CloudinaryImage.php index c14164e..4783091 100644 --- a/src-php/Fields/CloudinaryImage.php +++ b/src-php/Fields/CloudinaryImage.php @@ -49,10 +49,16 @@ public function __construct($name, $attribute = null, $disk = 'cloudinary', $sto 'fetch_format' => 'auto', ], $this->disk) : null; })->download(function () { + + // Get Cloudinary URL of image $image_address = cloudinary_image($this->value); + + // Get filename without folders + $filename = substr( strrchr( $this->value, '/' ), 1 ); + return response()->streamDownload(function () use ($image_address) { echo file_get_contents($image_address); - }, $this->value); + }, $filename); })->delete(function (Request $request, $model) { $path = pathinfo($model->{$this->attribute}); Storage::disk($this->disk)->delete($path['dirname'] .'/'. $path['filename']); From 20320b4e4f43ac94f44807166226307f7989708e Mon Sep 17 00:00:00 2001 From: Troels Johnsen Date: Fri, 12 Nov 2021 09:56:56 +0100 Subject: [PATCH 3/3] Update CloudinaryImage.php Fix missing dirname on delete --- src-php/Fields/CloudinaryImage.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src-php/Fields/CloudinaryImage.php b/src-php/Fields/CloudinaryImage.php index 4783091..f68acf5 100644 --- a/src-php/Fields/CloudinaryImage.php +++ b/src-php/Fields/CloudinaryImage.php @@ -61,7 +61,14 @@ public function __construct($name, $attribute = null, $disk = 'cloudinary', $sto }, $filename); })->delete(function (Request $request, $model) { $path = pathinfo($model->{$this->attribute}); - Storage::disk($this->disk)->delete($path['dirname'] .'/'. $path['filename']); + + $deletepath = $path['filename']; + + if(array_key_exists('dirname',$path) && $path['dirname'] != '.'){ + $deletepath = $path['dirname'] .'/'.$deletepath; + } + + Storage::disk($this->disk)->delete($deletepath); return $this->columnsThatShouldBeDeleted(); }); }