Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LiveComponent] Files validation #1739

Open
BaptisteChabrol opened this issue Apr 15, 2024 · 13 comments
Open

[LiveComponent] Files validation #1739

BaptisteChabrol opened this issue Apr 15, 2024 · 13 comments
Labels
LiveComponent Status: Waiting Feedback Needs feedback from the author

Comments

@BaptisteChabrol
Copy link

BaptisteChabrol commented Apr 15, 2024

Hello,

I have a problem to validate files with a DynamicForm.

There is my field :

$builder->add('fichierAudio', FileType::class, [
                'label' => 'Fichier audio',
                'required' => false,
                'mapped' => false,
                'help' => 'Merci de mettre un fichier de type mp3, mp4, ogg ou flac de moins de 200Mo auquel cas le fichier ne sera pas téléchargé.',
                'constraints' => [
                    new Assert\File(
                        maxSize: '200M',
                        maxSizeMessage: 'Le fichier est trop lourd. Max : 200Mo',
                        extensions: ['mp3', 'mp4', 'ogg', 'flac'],
                        extensionsMessage: "L'extension du fichier est invalide {{ extension }}, les extensions autorisées sont : {{ extensions }}",
                    )
                ]
            ])

Twig :

<div class="form-group">
    {{ form_label(form.fichierAudio) }}
    <div class="form-widget col-md-6 col-xxl-5">
        {{ form_widget(form.fichierAudio) }}

        <div class="form-text text-muted">
            Fichier téléchargé :
            {% if fichierAudioName %}
                {{ fichierAudioName }}
            {% else %}
                (Aucun)
            {% endif %}
        </div>

        {% if fichierAudioUploadError %}
            <div class="invalid-feedback d-block">{{ fichierAudioUploadError }}</div>
        {% endif %}

        <button data-action="live#action" data-live-action-param="files|uploadFile" class="btn btn-primary">
            Upload le fichier
        </button>
    </div>
    {{ form_help(form.fichierAudio) }}
    {{ form_errors(form.fichierAudio) }}
</div>

If I try to add file with this method, The form doesn't catch the error and the form is submitted. But if I do the constraint in the uploadFile method in my Form like this :

#[LiveAction]
	public function uploadFile(Request $request): void
	{
            $file = $request->files->get('rdv')['fichierAudio'];
            $this->validateFile($file);
            ...
	}

	private function validateFile(UploadedFile $file): void
	{
		$errors = $this->validator->validate($file, [
			new Assert\File(
				maxSize: '200M',
				maxSizeMessage: 'Le fichier est trop lourd. Max : 200Mo',
				extensions: ['mp3', 'mp4', 'ogg', 'flac'],
				extensionsMessage: 'L\'extension du fichier est invalide {{ extension }}, les extensions autorisées sont : {{ extensions }}',
			),
		]);

		if (0 === \count($errors)) {
			return;
		}

		$this->fichierAudioUploadError = $errors->get(0)->getMessage();
		throw new UnprocessableEntityHttpException('Validation failed');
	}

I have the validation error as I want but I can't replace the wrong file with another (It disappears from the form) and if the file is correct, the form is submitted si I don't want.

@smnandre
Copy link
Collaborator

There may be something you're doing different from the demo (https://ux.symfony.com/demos/live-component/upload) i think ... do you have LiveProp for this file ?

@WebMamba WebMamba added Status: Waiting Feedback Needs feedback from the author LiveComponent labels Apr 17, 2024
@BaptisteChabrol
Copy link
Author

Yes I have LiveProps for my file like in the demo :

    #[LiveProp]
    public ?string $fichierAudioName = null;

    #[LiveProp]
    public ?string $fichierAudioUploadError = null;

The only thing different I can see is that I'm in a symfony form

@smnandre
Copy link
Collaborator

File input cannot be handled with other data i think

@BaptisteChabrol
Copy link
Author

So there is no solution to add constraints to files with DynamicForm on symfony Form ?

@smnandre
Copy link
Collaborator

No, i'm saying you cannot have both Live action handling and standard form handling at the same time i think.

Not 100% sure to see who is who in your code, could you create a small reproducer ?

@BaptisteChabrol
Copy link
Author

BaptisteChabrol commented Apr 19, 2024

I reproduced the bug on this repo :
https://github.com/BaptisteChabrol/bug_app

@BaptisteChabrol
Copy link
Author

Any solutions ?

@smnandre
Copy link
Collaborator

I'm not sure because you have an error Warning: Trying to access array offset on null that fails the first two requests.

$file = $request->files->get('rdv')['fichierAudio'];

After that, i think you should reset the form error but you never do cause you return before

        if (0 === \count($errors)) {
            return;
        }
        
        // ...

Finally, while looking at the debugger, it seems you send two actions at once (upload and save) .. so i'd start there and look step by step what's going on :)

@BaptisteChabrol
Copy link
Author

The error Warning: Trying to access array offset on null occurs when you don't choose file before clicking on the upload file button.

I don't understand why I need to reset the form error before this return because if I enter in the if condition, I have no errors on the file validation (it's done like that in the demo but it works)

Plus, when there is an error and I want to upload another file, It doesn't go to the validateFile method (only when I click on the uploadFile button) because the file disappears before

@smnandre
Copy link
Collaborator

As i said, I think there are two actions at once. Could you check in your profiler / web debugger ?

@BaptisteChabrol
Copy link
Author

If I choose a file, and I click on the upload button, the save action is not called

image

@smnandre
Copy link
Collaborator

Could you look what the "_batch" is sending ?

@BaptisteChabrol
Copy link
Author

image

I don't see differences when I upload good or wrong file in the step, but if I click on the save button with a good file, I have a value on fichierAudioName :

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
LiveComponent Status: Waiting Feedback Needs feedback from the author
Projects
None yet
Development

No branches or pull requests

3 participants