oneduo / nova-file-manager

The most advanced File Manager for Laravel Nova, feature rich and robust build.
https://oneduo.github.io/nova-file-manager/
MIT License
129 stars 36 forks source link

Compatibility Issue whit whitecube/nova-flexible-content #392

Open sligregni opened 1 month ago

sligregni commented 1 month ago

Hi there,

I'm encountering a casting issue when using the whitecube/nova-flexible-content package alongside the oneduo/nova-file-manager package in a Laravel 10 application with Laravel Nova 4.

Description of the Issue When I use the FileManager field directly within a Nova resource, it works correctly and the path of the image is saved properly in the database. However, when I use the FileManager field within a flexible content layout (using whitecube/nova-flexible-content), I encounter a casting error upon loading the resource after saving.

Environment Laravel Framework 10.48.10 Laravel Nova 4 Nova flexible content : https://github.com/whitecube/nova-flexible-content

Error Details Here is the error message I receive:

TypeError: Oneduo\NovaFileManager\Support\Asset::__construct(): Argument #1 ($disk) must be of type string, stdClass given, called in /var/www/html/vendor/oneduo/nova-file-manager/src/FileManager.php on line 173

also the JSON saved value is not escaped [... "disk": "local", "path": "public/images/Become New Member/images.jpg".... ]

To Reproduce Steps to reproduce the behavior:

  1. Register a wrapper in NovaServiceProvider.php:

    public function register()
    {
        FileManager::registerWrapper('my_wrapper', function (FileManager $field) {
            // configure the field as you used to
            return $field
                ->multiple()
    
                ->filesystem(fn() => 'local')
                ;
        });
    
    }
  2. use the wrapper in FlexibleLayout

 namespace App\Nova\Flexible\Layouts;
use Oneduo\NovaFileManager\FileManager;
use Oneduo\NovaFileManager\NovaFileManager;
...
class FullwidthGalleryLayout extends Layout
{

...

public function fields()
    {
        return [
            FileManager::make('Gallery', 'gallery')->wrapper('my_wrapper'),
           // other fields
        ];
    }
    ...
    } 

This is the json valure store in the db:

[{"key": "ckFPysFFRRspqkS5", "layout": "fullwidth-gallery", "attributes": {"title": null, "cta_url": null, "gallery": [{"disk": "local", "path": "public/images/Become New Member/member.jpg"}], "cta_text": null, "subtitle": null, "cta_2_url": null, "cta_2_text": null, "cta_target": null, "cta_2_target": null, "focus_subtitle": null}}]

I would appreciate any guidance or solutions to resolve this issue. Specifically, how can I ensure that the FileManager field works correctly within a flexible content layout without causing errors?

Thank you in advance for your help! Simone

sligregni commented 1 month ago

I'm not very skilled on laravel but I found that the the wrapper pass to Asset Class a full flexible json instead the "gallery" field json So, the asset expect this: {"disk":"local","path":"public\/images\/Become New Member\/image.jpg"}

But the Flexible Content content Field is this:

[... {"disk": "local", "path": "public/images/Become New Member/images.jpg"}], "cta_text": null, "subtitle": null, "cta_2_url": null, "cta_2_text": null, "cta_target": null, "cta_2_target": null, "focus_subtitle": null}}]

So this raises the above error.

I read the "Third-party compatibility" section on the package document, but it seems referring to use flexible content in Nova setting.

Any helps will be really appreciate. Thanks, Simone

Rezrazi commented 1 month ago

Hi

Could you check these and see if it solves your issue: https://oneduo.github.io/nova-file-manager/installation.html#casting-your-model-attributes https://oneduo.github.io/nova-file-manager/field.html#third-party-compatibility

sligregni commented 1 month ago

Hi, Thanks for your answer!

Yes, I have already implemented the wrapper and casting.

  1. NovaServiceProvider.php
public function register()
    {

        FileManager::registerWrapper('my_wrapper', function (FileManager $field) {
                    // configure the field as you used to
                    return $field
                        ->multiple()
                        // ...
                        ->filesystem(fn() => 'public');
                });
    }
  1. Model
namespace App\Models\Content;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

use Illuminate\Database\Eloquent\Relations\MorphToMany;

use App\Models\Event\Event;

use Whitecube\NovaFlexibleContent\Concerns\HasFlexible;

use Spatie\EloquentSortable\Sortable;
use Spatie\EloquentSortable\SortableTrait;

use Oneduo\NovaFileManager\Casts\Asset;
use Oneduo\NovaFileManager\Casts\AssetCollection;

use Whitecube\NovaFlexibleContent\Value\FlexibleCast;

class ContentBlock extends Model  implements Sortable
{
    use HasFactory;

    use HasFlexible;
    use SortableTrait;

    public $sortable = [
        'order_column_name' => 'order',
        'sort_when_creating' => true,
        'sort_on_has_many' => true,
    ];

    protected $casts = [
        'background_image' => Asset::class, // use in Nova resource
        'gallery' => AssetCollection::class, // use in Nova resource       
        'flexible-content' => FlexibleCast::class,
        'image' => AssetCollection::class, // Use in Flexible Content Layout

    ];

    public function page()
    {
        return $this->belongsTo(Page::class);
    }

    public function template()
    {
        return $this->belongsTo(ContentTemplate::class);
    }

    public function event()
    {
        return $this->belongsTo(Event::class); 
    }

    public function contentItems()
    {
        return $this->hasMany(ContentItem::class);
    }

}
  1. The Flexible Content Layout:

namespace App\Nova\Flexible\Layouts;

use Oneduo\NovaFileManager\FileManager; use Laravel\Nova\Fields\Text; use Whitecube\NovaFlexibleContent\Layouts\Layout;

class ImageAndCaptionLayout extends Layout { /**

}

The errore I receive:

[2024-05-30 15:27:01] local.ERROR: Oneduo\NovaFileManager\Support\Asset::construct(): Argument #1 ($disk) must be of type string, stdClass given, called in /var/www/html/vendor/oneduo/nova-file-manager/src/FileManager.php on line 173 {"userId":1,"exception":"[object] (TypeError(code: 0): Oneduo\NovaFileManager\Support\Asset::construct(): Argument #1 ($disk) must be of type string, stdClass given, called in /var/www/html/vendor/oneduo/nova-file-manager/src/FileManager.php on line 173 at /var/www/html/vendor/oneduo/nova-file-manager/src/Support/Asset.php:20)



Thanks for help!
Simone
Rezrazi commented 1 month ago

can you please share the content from DB of background_image for the given model you're trying to apply this to?

sligregni commented 1 month ago

background_image field works as expected because is used inside a nova resource and it is a standard field on the db. Following is the the content of the field in db: { "disk": "local", "path": "public/images/Become EAS Member/rhodes.jpg" }

The problem is on image field because it has not a field on db, but is inside a layout in the flexible_content db field

Value of the db field flexible-content [ { "key": "cWGf8T5xCYaQHSkH", "layout": "imageandcaptionlayout", "attributes": { "image": [ { "disk": "public", "path": "images/Become EAS Member/eas_header.jpg" } ], "caption": "Caption text" } } ]

Very thanks to help me!

Fayne commented 1 month ago

Hi @Rezrazi ,

I'm facing some issue now. If i implemented this feature in Repeater field, it always show 404 error.

image

My environment is: Laravel Framework 10.48.11 Laravel Nova 4.34.2

I would be very grateful if you could take a look at this question.

Rezrazi commented 1 month ago

@sligregni @Fayne are you able to provide a minimal github repo that replicates your problem? We'll take a look at it and try to understand what's happening. It's not straightforward to debug without context. Cheers

sligregni commented 1 month ago

Hi @Rezrazi

I can't provide a github repo but I was able to replicate the problem with a fresh Laravel installation, just following this steps:

  1. Install Laravel 10 e Nova 4
  2. Install Flexible Content
  3. Install [File Manager] (https://github.com/oneduo/nova-file-manager/)
  4. configure the wrapper as you shown in the documentation
  5. Create a Nova resource with a Flexible layout, i use this [example] (https://whitecube.github.io/nova-flexible-content/#/?id=adding-layouts)
  6. Add a File Manager field in the Flexible Layout
  7. Use the layout in a Nova resource.

thanks for your support! Simone

Fayne commented 4 weeks ago

@sligregni @Fayne are you able to provide a minimal github repo that replicates your problem? We'll take a look at it and try to understand what's happening. It's not straightforward to debug without context. Cheers

Hi @Rezrazi ,

You can try this repository: https://github.com/Fayne/nova-file-manager-compatibility-demo

I added a field in User model which called profile. I'm using Nova native feature repeater fields. But when i click the file manage button, the url will show 404 error.

I'm using Herd 8.2 for PHP environment.

Thanks a lot.

image
mikaelpopowicz commented 4 weeks ago

Hi @Fayne

I just create this pull request to demonstrate how to use the package with Nova Repeater field.

This should solve you issue.

Hi @sligregni

I'm investigating on your issue, seems like an issue with the flexible cast.

Side note : flexible fields don't need any wrapper by default.

Regards.

Fayne commented 4 weeks ago

Hi @Fayne

I just create this pull request to demonstrate how to use the package with Nova Repeater field.

This should solve you issue.

Hi @sligregni

I'm investigating on your issue, seems like an issue with the flexible cast.

Side note : flexible fields don't need any wrapper by default.

Regards.

Hi @mikaelpopowicz

Thank you for your support.

I checked your updated, so my question is: if I want to use file manager in repeater fields, i have to manually call wrapper() function even filesystem changing is no necessary? If the answer is Yes, then i don't have further question. It's already resolved my problem. Just want to clarify what's the best way to use this package. 👍👍

mikaelpopowicz commented 4 weeks ago

Indeed, to use the field within a Repeatable from Nova you must register a wrapper even if the wrapper do nothing like

FileManager::registerWrapper('my_wrapper', fn (FileManager $field) => $field);
mikaelpopowicz commented 3 weeks ago

Hi @sligregni

Could you please provide a demo repository where you reproduce you issue like @Fayne?

I wasn't able to reproduce your issue. I just put some examples here on how to use the field.

Regards.