I’m trying to upload multiple files on Symfony but when the form is submitted the form image field returns a null object like this
object(DoctrineCommonCollectionsArrayCollection)#1455 (1) { ["elements":"DoctrineCommonCollectionsArrayCollection":private]=> array(1) { [0]=> object(AdminBundleEntityImageNew)#1717 (5) { ["nom":"AdminBundleEntityImageNew":private]=> NULL ["path":"AdminBundleEntityImageNew":private]=> NULL ["idimage":"AdminBundleEntityImageNew":private]=> NULL ["categorie":"AdminBundleEntityImageNew":private]=> NULL ["file":"AdminBundleEntityImageNew":private]=> NULL } } }
But when I get files directly inside the request files attributes file exist. I’ve tried to upload a file by accessing the attribute in the request, it works but it still wants to upload file via Symfony $form request handler.
That’s my controller
public function addColorAction(Request $request, Article $article) { $couleur = new Couleur(); $form = $this->createForm('AdminBundleFormCouleurType', $couleur); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $em = $this->getDoctrine()->getManager(); $files = $couleur->getImages(); echo "<pre>"; var_dump($files); die; $imgs = $request->files->get("adminbundle_couleur")["images"]; foreach ($imgs as $img) { $image = new ImageNew(); $image->setFile($img["file"]); $image->upload(); $couleur->addImage($image); $em->persist($image); $em->flush(); } $color_art_dispo = new CouleurArticleDispo(); $color_art_dispo->setEnStock(true); $color_art_dispo->setArticle($article); $color_art_dispo->setCouleur($couleur); $em->persist($couleur); $em->persist($color_art_dispo); $em->flush(); return $this->redirectToRoute('article_index'); } return $this->render( 'admin/article/couleur/new.html.twig', array( 'couleur' => $couleur, 'form' => $form->createView(),) ); }
The couleur entity
class Couleur { /** * @var int * * @ORMColumn(name="id", type="integer") * @ORMId * @ORMGeneratedValue(strategy="AUTO") */ private $id; /** * @var string * * @ORMColumn(name="nom", type="string", length=255) * @AssertNotBlank(message="Veuillez entrer le nom de la couleur") */ private $nom; /** * @var string * * @ORMColumn(name="code_couleur", type="string", length=6) * @AssertNotBlank(message="Veuillez entrer le code couleur correspondant") * @AssertLength( * min=6, * max=6, * minMessage="Le code couleur n'est pas correct.", * maxMessage="Le code couleur n'est pas correct.", * ) */ private $codeCouleur; /** * * @ORMOneToMany(targetEntity="CouleurArticleDispo", mappedBy="_couleurs") */ private $colorArticles; /** * Many Colors have Many Images. * * @ORMManyToMany(targetEntity="ImageNew",cascade={"remove"}) * @ORMJoinTable(name="color_images",joinColumns={@ORMJoinColumn(name="color_id",referencedColumnName="id", onDelete="CASCADE")}, * inverseJoinColumns={@ORMJoinColumn(name="image_id", referencedColumnName="idimage", onDelete="CASCADE")} * ) */ private $images; public function __toString() { return (string) $this->getNom(); } /** * Class Constructor */ public function __construct() { $this->images = new ArrayCollection(); } }
This is the image entity
class ImageNew { /** * @var string * * @ORMColumn(name="nom", type="string", length=100) */ private $nom; /** * @var string * * @ORMColumn(name="path", type="string", length=255) */ private $path; /** * @var integer * * @ORMColumn(name="idimage",type="integer") * @ORMId * @ORMGeneratedValue(strategy="IDENTITY") */ private $idimage; /** * @var AdminBundleEntityCategorie * * @ORMManyToOne(targetEntity="AdminBundleEntityCategorie",cascade={"persist"},inversedBy="slides") * @ORMJoinColumns({ * @ORMJoinColumn(name="id_categorie",referencedColumnName="idcategorie",nullable=true,onDelete="SET NULL") * }) */ private $categorie; /** * @AssertNotNull() * @AssertFile( * maxSize = "6000k", * mimeTypes = {"image/png", "image/jpg", "image/bmp"}, * mimeTypesMessage = "Please upload a valid Image File (PNG, JPEG or BMP)" * ) */ private $file; public function __toString() { return (string) $this->getPath(); } }
and this is the couleur type
class CouleurType extends AbstractType { /** * {@inheritdoc} */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('nom') ->add('codeCouleur') ->add( 'images', CollectionType::class, array( 'label' => 'Images de l'article ayant cette couleur', 'entry_type' => ImageNewFileType::class, 'allow_add' => true, 'allow_delete' => true, ) ); } }
and finally the image type
class ImageNewFileType extends AbstractType { /** * {@inheritdoc} */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add( 'file', FileType::class, [ 'mapped' => false, 'required' => false, 'attr' => array( 'accept' => 'image/*', ) ] ); } }
Advertisement
Answer
I think you shouldn’t add the mapped => false option in the ImageNewFileType.
https://symfony.com/doc/current/reference/forms/types/form.html#mapped
As you can see in the documentation the field is ignored when writing to the object.