Home > Net >  Symfony 6: embedded form Collection with File upload in child form
Symfony 6: embedded form Collection with File upload in child form

Time:01-17

I have an entity ClientFileAction which is parent to an entity Attachment in OneToMany relation. Attachment holds not only file path, but also information about files, like title, upload date, etc.

Attachment:

#[ORM\Column(type: 'string', length: 255)]
private $title;
#[ORM\Column(type: 'datetime')]
private $uploaded;
#[ORM\Column(type: 'string', length: 255)]
private $filePath;

When it comes to create a form type AttachmentType and upload files one to one, there is no problem:

AttachmentType:

$builder
    ->add('title', null, ['label' => 'Title', 'required' => true])
    ->add('attachmentFile', FileType::class, [
        'label' => 'File',
        'mapped' => false,
        'required' => true,
        'constraints' => [
            new File([
                'maxSize' => '1024k',
            ])
        ],
    ]);

In the controller I just get uploaded file with $attachmentFile = $form->get('attachmentFile')->getData(); and then proceed to the usual UploadedFile::move() stuff.

PROBLEM: EMBED AttachmentType IN PARENT FORM

But when I try to upload multiple attachments (not only files, but attachments with a title field), the uploaded file field seems to be unreachable.

ClientFileActionType:

$builder
    ->add('description', null, ['label' => 'Description', 'required' => true])
    ->add('attachments', CollectionType::class, ['label' => false,
                                            'allow_add' => true,
                                            'by_reference' => false,
                                            'entry_type' => AttachmentType::class,
                                            'entry_options' => ['label' => false],
                                    ]);

When I embed the AttachmentType as Collection inside ClientFileActionType, then, in the controller I don't find a way to get uploaded files:

$attachments = $form->get('attachments')->getData();

$attachments is an array of Attachment, and, as attachmentFile is not a mapped field, it dissapeared on the $form->handleRequest($request);.

I need a way to get unmapped attachmentFile fields of the child forms someway, something like:

$attachmentFiles = $form->get('attachments.attachmentFile')->getData();

That throws an error. Is there a correct way to do that?

CodePudding user response:

I found the correct way to do it as I was typing the question.

The uploaded files are in the Request object, so a correct approach for this scenario of file upload management could be:

if ($form->isSubmitted() && $form->isValid())
{
    $i=0;
    $files = $request->files->all('client_file_action')['attachments'];

    foreach ($files as $file)
    {
        $attachmentFile = $file['attachmentFile'];

        $originalFilename = pathinfo($attachmentFile->getClientOriginalName(), PATHINFO_FILENAME);
        
        $safeFilename = $slugger->slug($originalFilename);
        $newFilename = $safeFilename.'-' . uniqid() . '.' .$attachmentFile->guessExtension();

        $attachmentFile->move('path/to/folder',$newFilename);

        $attachment = $clientFileAction->findAttachment($i);

        if ($attachment != null)
            $attachment->setFilePath('path/to/folder/' . $newFilename);

        $i  ;
    }
    $clientFileActionRepository->add($clientFileAction, true);
}
  • Related