Я не нахожу решения в течение нескольких дней, чтобы решить мою проблему. Я хочу загрузить несколько изображений при создании сообщения. Объект My Post имеет отношение OneToMany к Image Entity. Я использую встроенную форму в моем PostType. Это CollectionType класса ImageType ::. Чтобы управлять моими функциями загрузки, я написал прослушиватель событий ImageUploadListener, который внедряет мой пользовательский сервис под названием FileUploader.
Этот слушатель вызывает функцию uploadFile при обработке события preUpdate и prePersist. Эта функция вызывает функцию загрузки из моего FileUploader, чтобы переместить изображение / файл … в целевой каталог и вернуть имя файла.
После этого я пытаюсь создать экземпляр Image Entity и установить соответствующие данные. Но это не работает, только файл, кажется, хранится правильно, но с дополнительной записью, нежелательной в моей БД. (В моей Таблице изображений для одного загруженного изображения у меня есть запись с идентификатором 1, например, post_id, установленный в NULL, и поле файла, установленное в / tmp / random number).
Пожалуйста, не могли бы вы помочь мне?
Post Entity
namespace UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Post
*
* @ORM\Table(name="post")
* @ORM\Entity(repositoryClass="UserBundle\Repository\PostRepository")
*/
class Post
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="Title", type="string", length=255)
*/
private $title;
/**
* @var string
*
* @ORM\Column(name="Content", type="text")
*/
private $content;/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="posts")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
/**
* @ORM\OneToMany(targetEntity="Image", mappedBy="post", cascade={"persist", "remove"})
*/
private $images;
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set title
*
* @param string $title
*
* @return Post
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set content
*
* @param string $content
*
* @return Post
*/
public function setContent($content)
{
$this->content = $content;
return $this;
}
/**
* Get content
*
* @return string
*/
public function getContent()
{
return $this->content;
}
/**
* Set post
*
* @param \
*
* @return Post
*/
public function setUser($user)
{
$this->user = $user;
return $this;
}
/**
* Get post
*
* @return \?
*/
public function getUser()
{
return $this->user;
}
/**
* Constructor
*/
public function __construct()
{
$this->images = new ArrayCollection();
}
/**
* Add image
*
* @param \UserBundle\Entity\Image $image
*
* @return Post
*/
public function addImage(\UserBundle\Entity\Image $image)
{
$this->images[] = $image;
return $this;
}
/**
* Remove image
*
* @param \UserBundle\Entity\Image $image
*/
public function removeImage(\UserBundle\Entity\Image $image)
{
$this->images->removeElement($image);
}
/**
* Get images
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getImages()
{
return $this->images;
}
}
Изображение Entity
namespace UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity(repositoryClass="UserBundle\Entity\ImageRepository")
*/
class Image
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;/**
* @ORM\Column(type="string", nullable=true)
*/
private $file;
public function setFile($file)
{
$this->file = $file;
return $this;
}
public function getFile()
{
return $this->file;
}/**
* @ORM\ManyToOne(targetEntity="Post", inversedBy="images")
* @ORM\JoinColumn(name="post_id", referencedColumnName="id")
*/
private $post;/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}/**
* Set post
*
* @param \UserBundle\Entity\Post $post
*
* @return Image
*/
public function setPost(\UserBundle\Entity\Post $post = null)
{
$this->post = $post;
return $this;
}
/**
* Get post
*
* @return \UserBundle\Entity\Post
*/
public function getPost()
{
return $this->post;
}
}
PostType
namespace UserBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
//use Ivory\CKEditorBundle\Form\Type\CKEditorType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use UserBundle\Entity\Post;class PostType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title')
->add('content')
->add('images', CollectionType::class, array (
'entry_type' => ImageType::class,
'entry_options' => array('label' => false),
'allow_add' => true,
'allow_delete' => true
))
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
//'data_class' => 'UserBundle\Entity\Post',
'data_class' => Post::class,
//'csrf_protection' => false
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'userbundle_post';
}}
ImageType
пространство имен UserBundle \ Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use UserBundle\Entity\Image;
class ImageType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('file', FileType::class, [
'required' => false,
'data_class' => null,
])
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Image::class,
//'csrf_protection' => false
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'userbundle_image';
}
}
РЕДАКТИРОВАТЬ: ImageUploadListener
//src/UserBundle/EventListener/ImageUploadListener.php
namespace UserBundle\EventListener;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\File\File;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use UserBundle\Entity\User;
use UserBundle\Entity\Post;
use UserBundle\Entity\Image;
use UserBundle\Service\FileUploader;class ImageUploadListener
{
private $uploader;public function __construct(FileUploader $uploader)
{
$this->uploader = $uploader;
}
public function prePersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$this->uploadFile($entity);
}
public function preUpdate(PreUpdateEventArgs $args)
{
$entity = $args->getEntity();
$this->uploadFile($entity);
}
private function uploadFile($entity)
{
if ($entity instanceof Post) {
$post = $entity;
$images = $post->getImages();
foreach ($images as $image) {
if ($image->getFile() instanceof UploadedFile) {
$imageName = $this->uploader->upload($image->getFile());
// to avoid persisting FileObject in DB
$post->removeImage($image);
$postImage = new Image();
$postImage->setFile($imageName);
$postImage->setPost($post);
$post->addImage($postImage);
}
}
}
return;
}
}
FileUploader
namespace UserBundle\Service;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class FileUploader
{
private $targetDir;
public function __construct($targetDir)
{
$this->targetDir = $targetDir;
}
public function upload(UploadedFile $file)
{
$fileName = md5(uniqid()).'.'.$file->guessExtension();
$file->move($this->getTargetDir(), $fileName);
return $fileName;
}
public function getTargetDir()
{
return $this->targetDir;
}
}
Задача ещё не решена.
Других решений пока нет …