[LiveComponent] Files validation
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.
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 ?
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
File input cannot be handled with other data i think
So there is no solution to add constraints to files with DynamicForm on symfony Form ?
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 ?
I reproduced the bug on this repo : https://github.com/BaptisteChabrol/bug_app
Any solutions ?
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 :)
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
As i said, I think there are two actions at once. Could you check in your profiler / web debugger ?
If I choose a file, and I click on the upload button, the save action is not called
Could you look what the "_batch" is sending ?
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 :
Thank you for this issue. There has not been a lot of activity here for a while. Has this been resolved?
Could I get an answer? If I do not hear anything I will assume this issue is resolved or abandoned. Please get back to me <3
Hey,
I didn't hear anything so I'm going to close it. Feel free to comment if this is still relevant, I can always reopen!
Thank you for this issue. There has not been a lot of activity here for a while. Has this been resolved?
Could I get an answer? If I do not hear anything I will assume this issue is resolved or abandoned. Please get back to me <3
Hey,
I didn't hear anything so I'm going to close it. Feel free to comment if this is still relevant, I can always reopen!
Hi @BaptisteChabrol ! Did you find a solution to handle file upload (with constraints) inside a live form with other data ?