I had a perfectly working multi files upload. Upload one file at a time with one "browse" button. It's basically a Places entity that can have Many images.
I am trying to modify it to upload all files at once through only one "browse" window. Select multiple files with Ctrl / shift.
So the first inside that I got is that VichUploader (VichFileType::class
) doesn't support multiple upload so only one option that I find so far is to change VichFileType::class
to FileType::class
in my AttachmentType.php
and add in options ['multiple' => true]
so now I have in my admin panel field with possibility to choose many files at once.This is exactly what i need. But after I chose all needed files and clicked Create
to create a new place I got error: Return value of Vich\UploaderBundle\Mapping\PropertyMapping::getFile() must be an instance of Symfony\Component\HttpFoundation\File\File or null, array returned
. It seems VichUploader waits only one file not array, so I modified my Images entity.
Before:
/**
* @param mixed $imageFile
*/
public function setImageFile($imageFile): void {
$this->imageFile = $imageFile;
if ($imageFile) {
$this->updatedAt = new \DateTime();
}
}
After:
/**
* @param mixed $imageFile
*/
public function setImageFile($imageFile): void {
foreach ($imageFile as $file) {
$this->imageFile = $file;
if ($imageFile) {
$this->updatedAt = new \DateTime();
}
}
}
After that, the error disappeared, but the problem is that if I add more than one picture, then only the last one from the array is added.
Full code:
Places.php
/**
* @ORM\OneToMany(targetEntity=Images::class, mappedBy="place", cascade={"persist", "remove"})
*/
private $images;
public function __construct()
{
$this->images = new ArrayCollection();
}
/**
* @return Collection|Images[]
*/
public function getImages(): Collection
{
return $this->images;
}
public function addImage(Images $image): self
{
if (!$this->images->contains($image)) {
$this->images[] = $image;
$image->setPlace($this);
}
return $this;
}
public function removeImage(Images $image): self
{
if ($this->images->removeElement($image)) {
// set the owning side to null (unless already changed)
if ($image->getPlace() === $this) {
$image->setPlace(null);
}
}
return $this;
}
Images.php
/**
* @ORM\Entity(repositoryClass=ImagesRepository::class)
* @Vich\Uploadable()
*/
class Images
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $title;
/**
* @Vich\UploadableField(mapping="attachments", fileNameProperty="title")
*/
private $imageFile;
/**
* @ORM\Column(type="datetime")
*/
private $updatedAt;
/**
* @ORM\ManyToOne(targetEntity=Places::class, inversedBy="images")
*/
private $place;
/**
* @ORM\ManyToOne(targetEntity=Regions::class, inversedBy="image")
*/
private $region;
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(?string $title): self
{
$this->title = $title;
return $this;
}
public function setUpdatedAt(\DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* @return mixed
*/
public function getUpdatedAt() {
return $this->updatedAt;
}
/**
* @param mixed $imageFile
*/
public function setImageFile($imageFile): void {
foreach ($imageFile as $file) {
$this->imageFile = $file;
if ($imageFile) {
$this->updatedAt = new \DateTime();
}
}
}
/**
* @return mixed
*/
public function getImageFile() {
return $this->imageFile;
}
public function getPlace(): ?Places
{
return $this->place;
}
public function setPlace(?Places $place): self
{
$this->place = $place;
return $this;
}
public function getRegion(): ?Regions
{
return $this->region;
}
public function setRegion(?Regions $region): self
{
$this->region = $region;
return $this;
}
}
AttachmentType.php
class AttachmentType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('imageFile', FileType::class, [
'multiple' => true
])
->add('updatedAt')
->add('place')
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Images::class,
]);
}
}