filamentphp / filament

A collection of beautiful full-stack components for Laravel. The perfect starting point for your next app. Using Livewire, Alpine.js and Tailwind CSS.
https://filamentphp.com
MIT License
17.33k stars 2.71k forks source link

FileUpload dimensions() validation #11904

Open valpuia604 opened 5 months ago

valpuia604 commented 5 months ago

Package

filament/filament

Package Version

v3.2.51

Laravel Version

v11.0.7

Livewire Version

v3.4.9

PHP Version

v8.3.4

Problem description

When rendering dynamic components based on different table/model, the rules() or rule() is not working in FileUpload, but If I used "predefine methods (?)" like ->required() it's working tho.. This same behaviour is working fine for TextInput, but not in FileUpload

Expected behavior

Expected that rules() or rule() working in dynamic components for FileUpload

Steps to reproduce

Install, check Post resource and you can see the rules() is working in TextInput but not in FileUpload

Reproduction repository

https://github.com/valpuia604/dynamic-component

Relevant log output

No response

Update:

I've check more and more and I think that ->rules([]) is not working in FileUpload whether it's dynamic or not

Donate 💰 to fund this issue

Fund with Polar

valpuia604 commented 5 months ago

If I put like this (without dynamic) then it's working

Forms\Components\FileUpload::make('img')
    ->label('img')
    ->image()
    ->required() // this is working
    ->rules([
        // 'required',
        'dimensions:width=100,height=200',
        // Rule::dimensions()->width(10)->height(50),
    ]),

But In dynamic it's not

Forms\Components\FileUpload::make('trans.'.$language->id.'.image')
    ->label('image')
    ->image()
    ->required() // this is working
    ->hiddenLabel()
    // below rules() is not working
    ->rules([
        // 'required',
        'dimensions:width=100,height=200',
        // Rule::dimensions()->width(10)->height(50),
    ]),

Screencast from 03-18-2024 02:01:55 PM.webm

danharrin commented 5 months ago

When #11907 is released, you'll be able to use nestedRecursiveRules() to pass these rules. The reason why it doesnt work is because the file upload always stores files in an array, even if there is only a singular file. So we need to pass these rules to each item in that array.

valpuia604 commented 5 months ago

Hi Dan, I've updated to 3.2.53 which contain #11907 and I use like below. But these validation are still not working.. Any idea

Forms\Components\FileUpload::make('img')
                    ->label('img')
                    ->image()
                    ->nestedRecursiveRules([
                        'required',
                        'dimensions:width=100,height=200',
                    ]),
danharrin commented 5 months ago

I've converted this to a feature request for a dimensions() method on the FileUpload which will allow us to investigate a better implementation

valpuia604 commented 5 months ago

For ease of checking dimensions, here are my finding in below environments

// rules() is working if Fileupload is not dynamic components
Forms\Components\FileUpload::make('img')
    ->rules([
        'dimensions:width=100,height=200',
    ]),

Screenshot from 2024-03-22 10-42-14

Using nestedRecursiveRules()

Forms\Components\FileUpload::make('img')
    ->nestedRecursiveRules([
        'dimensions:width=100,height=200',
    ]),

Screenshot from 2024-03-22 10-43-27

And now nestedRecursiveRules() seems to work (in dynamic component) which I said it's not working in https://github.com/filamentphp/filament/issues/11904#issuecomment-2005642189, but have problem in error message Screenshot from 2024-03-22 10-53-15

valpuia604 commented 5 months ago

It's also seems like I cannot change validation messages which is inside rules() or nestedRecursiveRules() for FileUpload

Forms\Components\FileUpload::make('img')
    ->required()
    ->rules([
        'dimensions:width=100,height=200',
    ])
    ->validationMessages([
        'required' => 'Error!!!!', // working
        'dimensions' => 'Dimension error!', // not working
    ])

Cause this one is working fine

Forms\Components\TextInput::make('name')
    ->rules([
        'required', 'min:3',
    ])
    ->validationMessages([
        'required' => 'Error!!!!',
        'min' => 'Min error!!',
    ]),
malzariey commented 5 months ago

It's also seems like I cannot change validation messages which is inside rules() or nestedRecursiveRules() for FileUpload

Forms\Components\FileUpload::make('img')
    ->required()
    ->rules([
        'dimensions:width=100,height=200',
    ])
    ->validationMessages([
        'required' => 'Error!!!!', // working
        'dimensions' => 'Dimension error!', // not working
    ])

Cause this one is working fine

Forms\Components\TextInput::make('name')
    ->rules([
        'required', 'min:3',
    ])
    ->validationMessages([
        'required' => 'Error!!!!',
        'min' => 'Min error!!',
    ]),

refer to this https://livewire.laravel.com/docs/validation#custom-key

binaryfire commented 3 months ago

Just sharing this related discussion: https://github.com/filamentphp/filament/discussions/5037

Wouldn't it be better performance-wise to implement this on the frontend using FilePond's image validate size plugin?

https://pqina.nl/filepond/docs/api/plugins/image-validate-size/

My main use case would be setting a min and max rather than exact dimensions. That'd prevent over- or under- sized images from ever hitting the server. Which would really reduce bandwidth and load.

simonhamp commented 2 months ago

Sorry to dive in on this one, it's the only related issue I could find before opening a new one... not sure if this actually related though.

I'm getting an issue when using a rule of 'dimensions:min_width=400,min_height=400'. When the validation fails, I get a bad gateway error locally (using Herd) and in prod it seems to trigger this TypeError: Illuminate\Translation\PotentiallyTranslatedString::__toString(): Return value must be of type string, null returned

I've had to remove the rule for now.

juliancc commented 1 month ago

Just sharing this related discussion: #5037

Wouldn't it be better performance-wise to implement this on the frontend using FilePond's image validate size plugin?

https://pqina.nl/filepond/docs/api/plugins/image-validate-size/

My main use case would be setting a min and max rather than exact dimensions. That'd prevent over- or under- sized images from ever hitting the server. Which would really reduce bandwidth and load.

Yeah this would be ideal. is this possible right now?