I'm using VichUploader in my Symfony2.3 application. I created one to one relationship between my Post entity and Image entity and I'm using Data Transformer for adding images through Post Form. Everything is working well, I'm getting no exception but post_id is not saved in Image table in database. Probably because of that every image I want to post is broken.
I would appreciate any help!
Image entity:
namespace BlogBundle\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;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* Class Image.
*
* @package Model
* @author Monika Malinowska
*
* @ORM\Table(name="images")
* @ORM\Entity(repositoryClass="BlogBundle\Repository\Image")
* @Vich\Uploadable
*/
class Image
{
/**
* @ORM\Id
* @ORM\Column(
* type="integer",
* nullable=false,
* options={
* "unsigned" = true
* }
* )
* @ORM\GeneratedValue(strategy="IDENTITY")
* @var integer $id
*/
private $id;
/**
* @ORM\OneToOne(targetEntity="Post", inversedBy="image")
* @ORM\JoinColumn(name="post_id", referencedColumnName="id")
*/
protected $post;
/**
*
* @Vich\UploadableField(mapping="image", fileNameProperty="imageName")
*
* @var File
*/
private $imageFile;
/**
* @ORM\Column(type="string", length=255)
*
* @var string
*/
private $imageName;
/**
* @ORM\Column(type="datetime")
*
* @var \DateTime
*/
private $updatedAt;
/**
*
* @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
*
* @return Image
*/
public function __construct()
{
$this->updatedAt= new \DateTime();
}
public function setImageFile(File $image = null)
{
$this->imageFile = $image;
if ($image) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->updatedAt = new \DateTime('now');
}
return $this;
}
/**
* @return File
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* @param string $imageName
*
* @return Image
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;
return $this;
}
/**
* @return string
*/
public function getImageName()
{
return $this->imageName;
}
/**
* Set Id.
*
* @param integer $id Id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* Get Id.
*
* @return integer Result
*/
public function getId()
{
return $this->id;
}
/**
* Set Post.
*
* @param integer $post Post
*/
public function setPost($post)
{
$this->post = $post;
}
/**
* Get Post.
*
* @return integer Result
*/
public function getPost()
{
return $this->post;
}}
Post Entity:
namespace BlogBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* Class Post.
*
* @package Model
*
* @ORM\Table(name="posts")
* @ORM\Entity(repositoryClass="BlogBundle\Repository\Post")
*/
class Post
{
/**
* @ORM\Id
* @ORM\Column(
* type="integer",
* nullable=false,
* options={
* "unsigned" = true
* }
* )
* @ORM\GeneratedValue(strategy="IDENTITY")
* @var integer $id
*/
private $id;
...
/**
* @ORM\OneToOne(targetEntity="Image", mappedBy="post")
*/
protected $image;
/**
* Get Id.
*
* @return integer Result
*/
public function getId()
{
return $this->id;
}
/**
* Set Id.
*
* @param integer $id Id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* Set image.
*
* @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
* @return $image
*/
public function setImage($image)
{
$this->image = $image;
return $this;
}
/**
* Get image.
*
* @return file Image
*/
public function getImage()
{
return $this->image;
}
/**
* Add images.
*
* @param \BlogBundle\Entity\Image $image
* @return Image
*/
public function addImage(\BlogBundle\Entity\Image $image)
{
$this->image = $image;
$image->setImage($this);
return $this;
}
/**
* Remove image
*
* @param \BlogBundle\Entity\Image $image
*/
public function removeImage(\BlogBundle\Entity\Image $image)
{
$this->$image->removeElement($image);
$image->setImage(null);
}
ImageType
namespace BlogBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormTypeExtensionInterface;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Form\Type\VichImageType;
/**
* Class ImageType.
*
* @package BlogBundle\Form
*/
class ImageType extends AbstractType
{
/**
* Form builder.
*
* @param FormBuilderInterface $builder Form builder
* @param array $options Form options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(
'id',
'hidden'
);
if (isset($options['validation_groups'])
&& count($options['validation_groups'])
&& !in_array('image-delete', $options['validation_groups'])
) {
// $builder->add('name', 'file', array('label' => 'Obrazek (format JPG)'));
//$builder->add('name', 'text');
$builder->add('imageFile', 'vich_image');
}
$builder->add(
'save',
'submit',
array(
'label' => 'Save'
)
);
}
/**
* Sets default options for form.
*
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'BlogBundle\Entity\Image',
'validation_groups' => 'image-default',
)
);
}
/**
* Getter for form name.
*
* @return string Form name
*/
public function getName()
{
return 'image_form';
}
}
PostType
namespace BlogBundle\Form;
use BlogBundle\Form\DataTransformer\TagDataTransformer;
use BlogBundle\Form\DataTransformer\ImageDataTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\HttpFoundation\File\File;
use BlogBundle\Form\ImageType;
/**
* Class PostType.
*
* @package BlogBundle\Form
*/
class PostType extends AbstractType
{
/**
* Form builder.
*
* @param FormBuilderInterface $builder Form builder
* @param array $options Form options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$imageDataTransformer = new ImageDataTransformer($options['image_model']);
$builder->add(
'id',
'hidden'
);
if (isset($options['validation_groups'])
&& count($options['validation_groups'])
&& !in_array('post-delete', $options['validation_groups'])
) {
...
$builder->add(
$builder
->create('image', 'file')
->addModelTransformer($imageDataTransformer)
);
}
$builder->add(
'save',
'submit',
array(
'label' => 'form.save'
)
);
}
/**
* Sets default options for form.
*
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'BlogBundle\Entity\Post',
'validation_groups' => 'post-default',
)
);
$resolver->setRequired(array('image_model'));
$resolver->setAllowedTypes(
array(
'image_model' => 'Doctrine\Common\Persistence\ObjectRepository'
)
);
}
/**
* Getter for form name.
*
* @return string Form name
*/
public function getName()
{
return 'post_form';
}
}
config.yml
vich_uploader:
db_driver: orm
mappings:
image:
uri_prefix: /assetic/images
upload_destination: '%kernel.root_dir%/../web/assetic/images'
namer: vich_uploader.namer_uniqid
inject_on_load: false
delete_on_update: true
delete_on_remove: true