Closed azim-kordpour closed 2 months ago
@azim-kordpour it seems you are missing the folder
setting in filesystems.php
'cloudinary' => [
'driver' => 'cloudinary',
'cloud_name' => env('CLOUDINARY_CLOUD_NAME'),
'api_key' => env('CLOUDINARY_API_KEY'),
'api_secret' => env('CLOUDINARY_API_SECRET'),
'url' => [
'secure' => (bool) env('CLOUDINARY_SECURE_URL', true),
],
'folder' => env('CLOUDINARY_FOLDER'),
],
Could you update this?
Please share what is the expected url should be.
Please share how you have implemented with Filament.
The problem is extension
.
When I set LIVEWIRE_TEMPORARY_DISK=cloudinary
I get this message
Illuminate\Filesystem\FilesystemAdapter::Illuminate\Filesystem{closure}(): Argument #1 ($attributes) must be of type League\Flysystem\StorageAttributes, array given, called in /var/www/html/vendor/league/flysystem/src/DirectoryListing.php on line 33
I checked the temporary directory of Livewire on the Cloudinary panel and the picture was there.
Then, I changed LIVEWIRE_TEMPORARY_DISK=public
, and the upload was done, but the image did not displayed (404).
This was the URL:
and this works:
It is mentioned in the document not to save the extension. It's not an appropriate approach to save a file without an extension and retrieve it with an extension.
Hey @azim-kordpour
Thanks for your message.
We save and submit Cloudinary's Public ID to the database. So whatever Key you send to Cloudinary is the PublicID, not the FilePath. The extension needs to be specified when you retrieve the file. Thats why your second example works.
01HT2BYSR6JWREQQY46DF3QN4E.jpg => Cloudinary Public ID
01HT2BYSR6JWREQQY46DF3QN4E.jpg.jpg => Get Image as JPG
01HT2BYSR6JWREQQY46DF3QN4E.jpg.png => Get Image as PNG
01HT2BYSR6JWREQQY46DF3QN4E.jpg.webp => Get Image as WEBP
We use a helper method on the model to retrieve Cloudinary images and specify the format there.
public function getImage($imageFormat = '.webp')
{
switch ($this->image_disk) {
case 'url':
case 'cloudinary':
return $this->image . $imageFormat;
default:
return Storage::disk($this->image_disk)->url($this->image);
}
}
Best regards Sebastian
Hey @azim-kordpour
I've updated my previous post.
Best regards Sebastian
@StanBarrows
Thank you for the explanation.
To solve my problem, I changed the media model in the configuration file of the media library to override file_name by an accessor.
Hey @azim-kordpour
We can not return a working string or reference to the file because we're currently unaware of the file type (extension). Although we could store it directly within the Cloudinary Public ID, I remember that using dots "." in the ID caused problems in the past, so we decided against it.
I am open to creating a concept to save the Cloudinary input in a JSON Database field.
[
'file_disk'=> cloudinary,
'file_type'=> 'jpg'
''file_id' => '12345'
]
However, this would make the whole integration more complex, and another downside would be that it would then be difficult to switch between Laravel storage drivers just by changing the filesystem's .env values.
In our current applications, We use for every field that is linked to a storage driver a "field_disk" column so that I can always use multiple drivers in my application. For example, for testing.
But, we will update and improve the docs so that it is clear that the handling of this package is more related to storing and updating data in Cloudinary. The handling needs to be done based on the integration usage. We'll shortly provide a Fillament Image Field.
For filament I have taken their random filenames from here https://github.com/filamentphp/filament/blob/3.x/packages/forms/src/Components/BaseFileUpload.php#L180.
And applied it up cloudinary uploads without the extension.
FileUpload::make('fallback_images')
->image()
->multiple()
->getUploadedFileNameForStorageUsing(
fn (): string => (string) Str::ulid()
)
->disk('cloudinary'),
]),
If you need the original extension you can just add it as another attribute to save. (https://filamentphp.com/docs/3.x/forms/fields/file-upload#storing-original-file-names-independently)
I am probably going to disable the api calls on load too since it delays a bit. https://filamentphp.com/docs/3.x/forms/fields/file-upload#prevent-file-information-fetching
And here is my full config which applies only when you use ->image()
in the FileUpload
.
FileUpload::configureUsing(function (FileUpload $fileUpload) {
$fileUpload->disk(function (FileUpload $component) {
// this means the FileUpload was created with `->image()`
if ($component->getAcceptedFileTypes() == ['image/*']) {
return 'cloudinary';
}
return null;
})->fetchFileInformation(function (FileUpload $component) {
return ! ($component->getDisk()->getAdapter() instanceof FlysystemCloudinaryAdapter);
});
});
FileUpload::configureUsing(function (FileUpload $fileUpload) {
$fileUpload->getUploadedFileNameForStorageUsing(function (FileUpload $component, TemporaryUploadedFile $file) {
if ($component->getDisk()->getAdapter() instanceof FlysystemCloudinaryAdapter) {
return Str::ulid();
}
return $component->shouldPreserveFilenames() ? $file->getClientOriginalName() : (Str::ulid().'.'.$file->getClientOriginalExtension());
});
}, isImportant: true);
@robclancy Do you know how to change the file when using TextEditor file attachment. Your random file name in getUploadedFileNameForStorageUsing is great but Idk how to fix it also in the editor file attachments.
Problem: the uploaded attachment file will also use the extension(.jpg, .pne) so it can't be render after uploaded.
Oh I found out
TinyEditor::make('body')
->toolbarSticky(true)
->required()
->columnSpanFull()
->fileAttachmentsDisk('cloudinary')
->fileAttachmentsDirectory('blogs')
->saveUploadedFileAttachmentsUsing(function (TemporaryUploadedFile $file) {
return $file->storeAs('blogs', Str::random(30), 'cloudinary');
}),
Yep. I have done similar. This is my final workaround.
if (config('filament.default_filesystem_disk') == 'cloudinary') {
FileUpload::configureUsing(function (FileUpload $fileUpload) {
$fileUpload->fetchFileInformation(false);
});
FileUpload::configureUsing(function (FileUpload $fileUpload) {
$fileUpload->getUploadedFileNameForStorageUsing(function () {
return Str::ulid();
});
}, isImportant: true);
RichEditor::configureUsing(function (RichEditor $editor) {
$editor->saveUploadedFileAttachmentsUsing(function (RichEditor $editor, TemporaryUploadedFile $file) {
return $file->storePubliclyAs($editor->getFileAttachmentsDirectory(), Str::ulid(), $editor->getFileAttachmentsDiskName());
});
});
}
Question or Feature?
Hi, To make a long story short, the images are uploaded and I can see them in the cloudinary panel but the generated URLs get 404.
I'm using filament and Spatie Media Library and these are my configurations:
in filesystems.php:
in .env
The URL is like this:
Could you please guide me?