It is a very common use case to upload a file along with other input data when dealing with Symfony forms. When you have a form that involves a one to many or many to many relationships, you may follow this example:

 

Prerequisites:

 

To allow users to upload a files in the previous example, we'll modify the AuthorType form to include a FileType field that will enable the uploading of files associated with each author. Additionally, we'll update the BookType form to enable file uploads for each author. Let's assume we want to add a file upload field for the "avatar" of each author.

 

Update the Author Entity:

Add a new property to the "Author" entity to store the avatar image filename.

// src/Entity/Author.php
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class Author
{
    // ... other properties and annotations ...

    /**
     * @ORM\Column(type="string", nullable=true)
     */
    private $avatarFilename;

    // ... getters and setters ...
}

 

Update the AuthorType Form:
Update the "AuthorType" form to include a FileType field for the avatar upload.

// src/Form/AuthorType.php
namespace App\Form;

use App\Entity\Author;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class AuthorType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class)
            ->add('avatar', FileType::class, [
                'label' => 'Avatar (JPEG/PNG file)',
                'required' => false,
                'mapped' => false, // This is not a property of the Author entity
            ]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Author::class,
        ]);
    }
}

 

Update the BookType Form:
Update the "BookType" form to allow multiple file uploads for each author.

// src/Form/BookType.php
namespace App\Form;

use App\Entity\Book;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class BookType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title', TextType::class)
            ->add('authors', CollectionType::class, [
                'entry_type' => AuthorType::class,
                'allow_add' => true,
                'allow_delete' => true,
                'by_reference' => false,
            ]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Book::class,
        ]);
    }
}

 

Update the Twig Template:
Update the Twig template to include the file upload field for each author in the "authors" collection.

{# templates/book/create_book.html.twig #}
{% extends 'base.html.twig' %}

{% block content %}
    <h1>Create Book</h1>
    {{ form_start(form) }}
    {{ form_row(form.title) }}
    <h2>Authors</h2>
    <ul id="authors-list">
        {% for authorForm in form.authors %}
            <li>
                {{ form_row(authorForm.name) }}
                {{ form_row(authorForm.avatar) }}
                <a href="#" class="remove-author-link">Remove</a>
            </li>
        {% endfor %}
    </ul>
    <a href="#" id="add-author-link">Add Author</a>
    <button type="submit">Create Book</button>
    {{ form_end(form) }}

    <script>
        // JavaScript to handle adding and removing author forms
        // (Same as the previous example)
    </script>
{% endblock %}

Now, when you access the "/book/create" or "/book/update/{id}" route, the form will display a file upload field for each author in the "authors" collection.

Users can upload avatar images for each author along with other information about the book and its authors.