UPDATED In my Symfony project,I am able to upload single image.Now I am trying to upload multiple images.
class ImageFile extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('images', FileType::class, array(
'attr' => array(
'accept' => 'image/*',
'multiple' => 'multiple'
)
))
->add('save',SubmitType::class,array('label'=>'Insert Image','attr'=>array('class'=>'btn btn-primary','style'=>'margin-bottom:15px')))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => images::class
));
}
}
In my Images entity, I keep an array of SatellieImage objects like this.
class images
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @var satelliteImage[]
* @ORM\Column(name="images", type="string")
*
*/
private $images;
/**
* Set images
*
* @param string $images
*
* @return satelliteImage[]
*/
public function setImages($images)
{
$this->images = $images;
return $this->images;
}
/**
* Get images
*
* @return satelliteImage[]
*/
public function getImages()
{
return $this->images;
}
public function addImage($image)
{
$this->images[] = $image;
return $this;
}
}
And in my controller, I store the satelliteImage[] as $files and run a foreach loop to upload() each file (upload() function worked perfectly for single file)
public function uploadImages(Request $request)
{
$satelliteImage=new satelliteImage;
$images=new images();
$form = $this->createForm(ImageFile::class, $images);
$form->handleRequest($request);
$files=$images->getImages();
foreach ($files as $file){
$em=$this->getDoctrine()->getManager();
$file->upload();
$em->persist($satelliteImage);
$em->flush();
}
$this->addFlash(
'notice',
'Images inserted successfully'
);
return $this->redirectToRoute('satellite_images');
}
Problem : I get an error saying "Warning: Invalid argument supplied for foreach()" How do I fix this?
I think all you have to do here is add the 'multiple' attribute to your ImageFile
class;
See Symfony documentation.
use Symfony\Component\Form\Extension\Core\Type\FileType;
class ImageFile extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('images', FileType::class, [
'multiple' => true,
'attr' => [
'accept' => 'image/*',
'multiple' => 'multiple'
]
])
;
}
}
Also, change your 'image' property, to 'images' property:
/**
* Set images
*
* @param string $images
*
* @return satelliteImage[]
*/
public function setImages($images)
{
$this->images = $images;
return $this;
}
/**
* Get images
*
* @return string
*/
public function getImages()
{
return $this->image;
}
public function addImage($image)
{
$this->images[] = $image;
return $this;
}
Once you have this sorted, you can modify your upload
method to handle multiple files from the FormType.
Maybe working example help you? I make simple app with multipe file upload for symfony 3.*. Here is link: https://github.com/marekz/example_symfony_multiply_files_example
First: Both form declatartion:
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use AppBundle\Form\FilesType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
class UserType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('lastName')
->add('files', CollectionType::class,array(
'entry_type' => FilesType::class,
'allow_add' => true,
'by_reference' => false,
))
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\User'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_user';
}
}
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class FilesType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('file');
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Files'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_files';
}
}
Now, my entities:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* User
*
* @ORM\Table(name="user")
* @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
*/
class User {
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @var string
*
* @ORM\Column(name="lastName", type="string", length=255)
*/
private $lastName;
/**
* @ORM\ManyToMany(targetEntity="Files", cascade={"persist"})
*/
private $files;
function __construct() {
$this->files = new ArrayCollection();
}
/**
* Get id
*
* @return int
*/
public function getId() {
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return User
*/
public function setName($name) {
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName() {
return $this->name;
}
/**
* Set lastName
*
* @param string $lastName
*
* @return User
*/
public function setLastName($lastName) {
$this->lastName = $lastName;
return $this;
}
/**
* Get lastName
*
* @return string
*/
public function getLastName() {
return $this->lastName;
}
/**
* Get files
*
* @return ArrayCollection
*/
function getFiles() {
return $this->files;
}
/**
* Set files
* @param type $files
*/
function setFiles($files) {
$this->files = $files;
}
}
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Files
*
* @ORM\Table(name="files")
* @ORM\Entity(repositoryClass="AppBundle\Repository\FilesRepository")
*/
class Files
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="file", type="string", length=255, unique=true)
* @Assert\NotBlank(message="Please, upload the product brochure as a PDF file.")
* @Assert\File(mimeTypes={ "application/pdf" })
*/
private $file;
/**
*
* @return Files
*/
function getUser() {
return $this->user;
}
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set file
*
* @param string $file
*
* @return Files
*/
public function setFile($file)
{
$this->file = $file;
return $this;
}
/**
* Get file
*
* @return string
*/
public function getFile()
{
return $this->file;
}
}
Finaly, Symfony Controller:
/**
* Creates a new user entity.
*
* @Route("/new", name="user_new")
* @Method({"GET", "POST"})
*/
public function newAction(Request $request) {
$user = new User();
$form = $this->createForm('AppBundle\Form\UserType', $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$attachments = $user->getFiles();
if ($attachments) {
foreach($attachments as $attachment)
{
$file = $attachment->getFile();
var_dump($attachment);
$filename = md5(uniqid()) . '.' .$file->guessExtension();
$file->move(
$this->getParameter('upload_path'), $filename
);
var_dump($filename);
$attachment->setFile($filename);
}
}
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
return $this->redirectToRoute('user_show', array('id' => $user->getId()));
}
return $this->render('user/new.html.twig', array(
'user' => $user,
'form' => $form->createView(),
));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With