Search code examples
phpsymfonytwigsymfony4

How to display error on my input file on Symfony 4?


I work on my first symfony project and I need to create nice errors for a form with an uploading input.

Actually, I change with success my parameters to a limit post of 20Mo and a limit size for an uploaded file of 20Mo.

In my entity, I have an Assert (by symfony) on my property "portfolio".

    /**
 * @Assert\File(
 *     maxSize="5M",
 *     mimeTypes = {"application/pdf"},
 *     mimeTypesMessage = "Votre fichier doit être au format PDF"
 * )
 */
public $portfolio;

Btw i made my import like asked in the symfony documentation.

I have the twig expression to display my errors directly when i try to validate a wrong form.

Here is my controller's function :

  public function formjob(\Swift_Mailer $mailer, Request $request)
{
    $job = new JobForm();

    $form = $this->createFormBuilder($job)
        ->add("name", TextType::class, [
            "label" => "Nom :"
        ])
        ->add("firstName", TextType::class, [
            "label" => "Prénom :"
        ])
        ->add("mail", EmailType::class, [
            "label" => "E-mail :"
        ])
        ->add("telephone", TelType::class, [
            "label" => "Tel. ",
            "required" => false,
            "empty_data" => "Non Renseigné"
        ])
        ->add("url", UrlType::class, [
            "label" => "Envoyez-nous l’adresse internet vers vos réalisations",
            "required" => false,
        ])
        ->add("portfolio", FileType::class, [
            "label" => "Envoyez votre portfolio au format PDF",
            "required" => false,
            "error_bubbling" => true
        ])
        ->add("envoyer", SubmitType::class)
        ->getForm();

    $form->handleRequest($request);


    if($form->isSubmitted() && $form->isValid()) {

        $data = $form->getData();
        $attachment = $data->portfolio;
        $mail = $data->mail;
        if(isset($attachment) || isset($data->url)) {
            $message = (new \Swift_Message())
                ->setSubject('Formulaire Job')
                ->setFrom($mail)
                ->setTo('[email protected]')
                ->setBody(
                    $this->renderView(
                        'mail/mailjob.html.twig', [
                            'data' => $data
                        ]
                    ),
                    'text/html'
                );
            if (isset($attachment)) {
                $message->attach(\Swift_Attachment::fromPath($attachment)->setFilename('portfolio.pdf')->setContentType('application/pdf'));
            }
            $mailer->send($message);

            return $this->redirectToRoute('sent');
        }
    }
    return $this->render('main/formJob.html.twig', [
        'form'=> $form->createView(),
    ]);
}

And here is my template :

    {% extends 'layout.html.twig' %}{% block title %}Jobs{% endblock %}{% block stylesheets %}<link rel="stylesheet" type="text/css" href="formJobs.css"> {%  endblock %}{% block body %}<div class="row">
    <div class="col-lg-12">
        <h1 class="antiqueO">Postuler</h1>

        <h2 class="robotoR">Intitulé du poste</h2>
        <h3 class="robotoM">Type de poste</h3>

        <p class="robotoR">Description du poste</p>

        <div class="trait_noir_separation"></div>

        {{ form_start(form) }}
            <div class="col-lg-12">
                {{ form_label(form.name) }}
            </div>
            <div class="col-lg-12">
                {{ form_errors(form.name) }}
                {{ form_widget(form.name) }}
            </div>

        <div class="col-lg-12">
            {{ form_label(form.firstName) }}
        </div>
        <div class="col-lg-12">
            {{ form_errors(form.firstName) }}
            {{ form_widget(form.firstName) }}
        </div>

        <div class="col-lg-12">
            {{ form_label(form.mail) }}
        </div>
        <div class="col-lg-12">
            {{ form_errors(form.mail) }}
            {{ form_widget(form.mail) }}
        </div>

        <div class="col-lg-12">
            {{ form_label(form.telephone) }}
        </div>
        <div class="col-lg-12">
            {{ form_errors(form.telephone) }}
            {{ form_widget(form.telephone) }}
        </div>

        <div class="col-lg-12">
            {{ form_label(form.url) }}
        </div>
        <div class="col-lg-12">
            {{ form_errors(form.url) }}
            {{ form_widget(form.url) }}
        </div>

        <div class="col-lg-12">
            {{ form_label(form.portfolio) }}
        </div>
        <div class="col-lg-12">
            {{ form_errors(form.portfolio) }}
            {{ form_widget(form.portfolio, {'attr': {'class': 'form-control-file', 'accept' : 'application/pdf'}})}}
        </div>
        <div>
            {{ form_widget(form.envoyer, {'attr': {'class': 'antiqueO send_button'}}) }}
        </div>
        {{ form_end(form) }}
    </div>
</div>{% endblock body %}

Actually i have a problem : all my errors can be triggered and displayed. BUT the error on my file input refuse to be displayed even if i have the error in my profiler toolbar :

Profiler Toolbar for size error

Profiler Toolbar for format error

What is the problem in my code? What is blocking my error display?


Solution

  • Based in https://symfony.com/doc/current/reference/forms/types/text.html#error-bubbling

    error_bubbling type: boolean default: false unless the form is compound

    If true, any errors for this field will be passed to the parent field or form. For example, if set to true on a normal field, any errors for that field will be attached to the main form, not to the specific field.

    So as you are using this attribute in portfilo property, the error is showing on

    {{ form_errors(form) }}

    and not in

    {{ form_errors(form.portfolio) }}
    

    Just try to remove error_bubbling from portfolio property in formjob function and the error should be showed in your form