Загрузить несколько изображений с помощью Symfony без дополнительных пакетов

У меня проблема, когда я пытаюсь загрузить более одного изображения в базу данных.
Я прочитал документы Symfony и могу загружать одно изображение за раз.
Я также прочитал

http://symfony.com/doc/current/cookbook/form/form_collections.html

До сих пор я полностью понимаю процесс загрузки ОДНОГО ИЗОБРАЖЕНИЯ, но что происходит, когда вам нужно загрузить более одного изображения?
Вот моя ситуация: у меня есть сущность Store и сущность StorePhoto, а Store содержит отношение OneToMany с StorePhoto (переменная commerce_photos) (я разрабатываю некую галерею изображений для магазина).
Идея состоит в том, чтобы загружать более одного изображения за раз, я имею в виду выбрать более одного файла и загрузить их.
Вот что я сделал

Мой магазин

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
* @ORM\Entity
* @ORM\Table(name="store")
*
*/

class Store{

/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;

/**
* @ORM\Column(type="string", length=255)
*/
protected $name;

/**
* @ORM\OneToOne(targetEntity="StorePhoto")
*/
protected $photo;

/**
* @ORM\OneToMany(targetEntity="StorePhoto", mappedBy="store_photo")
*/
protected $commerce_photos;

public function __construct(){
$this->commerce_photos = new ArrayCollection();
}/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}

/**
* Set name
*
* @param string $name
* @return Store
*/
public function setName($name)
{
$this->name = $name;

return $this;
}

/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}

/**
* Add commerce_photos
*
* @param \AppBundle\Entity\StorePhoto $commercePhotos
* @return Store
*/
public function addCommercePhotos(\AppBundle\Entity\StorePhoto $commercePhotos)
{
$this->commerce_photos[] = $commercePhotos;

return $this;
}

/**
* Remove commerce_photos
*
* @param \AppBundle\Entity\StorePhoto $commercePhotos
*/
public function removeCommercePhotos(\AppBundle\Entity\StorePhoto $commercePhotos)
{
$this->commerce_photos->removeElement($commercePhotos);
}

/**
* Get commerce_photos
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getCommercePhotos()
{
return $this->commerce_photos;
}
}

Моя сущность StorePhoto

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;/**
* @ORM\Entity
* @ORM\Table(name="store_photo")
*/

class StorePhoto{

/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;

/**
* @ORM\Column(type="string", length=255)
*/
protected $imageName;

/**
* @ORM\Column(type="string", length=255,nullable=false)
*/
protected $path;

/**
* @ORM\ManyToOne(targetEntity="Store", inversedBy="commerce_photos")
*/
protected $store_photo;

/**
* @Assert\Image
(mimeTypes = {"image/jpg", "image/jpeg", "image/gif", "image/png"},
mimeTypesMessage = "Solo acepta imagenes en formato JPG, GIF ou PNG.",
maxSize="5000k")
*/
private $imageFile;

/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}

/**
* Get file.
*
* @return UploadedFile
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* Sets file.
*
* @param UploadedFile $imageFile
*/
public function setImageFile(UploadedFile $file = null)
{
$this->imageFile = $file;
}
/**
* Set imageName
*
* @param string $imageName
* @return StorePhoto
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;

return $this;
}

/**
* Get imageName
*
* @return string
*/
public function getImageName()
{
return $this->imageName;
}

/**
* Set store_photo
*
* @param \AppBundle\Entity\Store $storePhoto
* @return StorePhoto
*/
public function setStorePhoto(\AppBundle\Entity\Store $storePhoto = null)
{
$this->store_photo = $storePhoto;

return $this;
}

/**
* Get store_photo
*
* @return \AppBundle\Entity\Store
*/
public function getStorePhoto()
{
return $this->store_photo;
}
public function getAbsolutePath()
{
return null === $this->path
? null
: $this->getUploadRootDir().'/'.$this->path;
}
public function getWebPath()
{
return null === $this->path
? null
: $this->getUploadDir().'/'.$this->path;
}
protected function getUploadRootDir()
{
//the absolute directory where uploaded documents should be saved
return __DIR__.'/../../../../web/images'.$this->getUploadDir();

}
protected function getUploadDir()
{
//get rid of the __DIR__ so it doesn't screw up
//when displaying uploaded doc/image in the view
return 'uploads/documents';

}
public function upload()
{
//the file property can be empty if the field is not required

if(null === $this->getImageFile())
{
return;
}
//use the original file name here but you should
//sanitaze it at least to avoid any security issues

//move takes the target directory and then the target filename to move to.
$this->getImageFile()->move(
$this->getUploadRootDir(), $this->getImageFile()->getClientOriginalName()
);

//set the path property to the filename where you've saved the file
$this->path = $this->getImageFile()->getClientOriginalName();
//clean up the file property as you won't need it anymore...
$this->imageFile = null;

}

}

Мой контроллер

<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use AppBundle\Forms\Type\FileUploadType;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Entity\StorePhoto;
use AppBundle\Entity\Store;
use Symfony\Component\HttpFoundation\Response;
use AppBundle\Forms\Type\MultipleFileUploadType;class DefaultController extends Controller
{

public function multipleFileUploadAction(Request $request)
{
$store = new Store();

$store->setName('Test01');

$store->addCommercePhotos(new StorePhoto());

$form = $this->createForm(new MultipleFileUploadType(),$store);

$form->handleRequest($request);

if($form->isValid())
{
$em = $this->getDoctrine()->getManager();

$em->persist($store);

$em->flush();

return new Response('200 OK...');
}

return $this->render('Forms/FileUpload.html.twig',array('form'=>$form->createView()));}
}

Мои формы сейчас, FileUploadType и MultipleFileUploadType

<?php
namespace AppBundle\Forms\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class FileUploadType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('imageName', 'text');
$builder->add('imageFile', 'file',
array('multiple'=>'multiple'));
//  $builder->add('Save', 'submit');

}
public function getName()
{
return "storePhoto";

}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\StorePhoto',
));}
}

?>

<?php
namespace AppBundle\Forms\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use AppBundle\Forms\Type\FileUploadType;

class MultipleFileUploadType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name','text');
$builder->add('commerce_photos', 'collection',array(
'type' => new FileUploadType()));
$builder->add('Save', 'submit');

}
public function getName()
{
return "MultipleFileUpload";

}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Store',
));
}
}

?>

Вот и весь код, я не знаю, что я здесь что-то упускаю.
Что мне нужно сделать, это отобразить диалоговое окно, выбрать несколько изображений и затем сохранить их.
В этом случае в контроллере я написал эту строку

    $store = new Store();

$store->setName('Test01');

$store->addCommercePhotos(new StorePhoto());

В этом случае, когда я отрисовываю форму, она показывает мне диалоговое окно и позволяет мне выбрать только один файл.
Если я удаляю третью строку, addCommerce … Он показывает только ярлык commercePhotos.

Заранее спасибо!

0

Решение

Пока вы не установите значение для поля commerce_photos, Symfony будет распознавать его как пустое. Для пустого поля не будет отображаться элемент ввода. Так что вам нужно установить какое-нибудь фиктивное значение или визуализировать поле самостоятельно так:

{{ form_label(form.imageFile) }}
<input type="file" name="{{ form.imageFile.vars.fullName }}[]" class="file-upload" />

Квадратные скобки важны для того, чтобы Symfony обрабатывал несколько значений. Чтобы заставить форму принимать несколько файлов одновременно, вам может понадобиться такой jquery:

$('.file-upload').on('change', function (event) {
$(event.currentTarget).after('<input type="file" name="{{ form.imageFile.vars.fullName }}[]" class="file-upload" />');
});
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]