我有以下表单类型:
class GalleryImageType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('thumb', new GalleryThumbnailImage(), array('label' => 'Thumbnail Image'))
->add('full', new GalleryFullSizeImage(), array('label' => 'Full Size Image'));
}
public function getName()
{
return 'galleryImage';
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array('data_class' => 'MajorProductions\SewingDiva\SiteBundle\Entity\GalleryImage'));
}
}
以下实体:
/**
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
* @ORM\Table(name="GalleryImage", indexes={@ORM\Index(name="id_idx", columns={"id"})})
*/
class GalleryImage
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\OneToOne(targetEntity="GalleryThumbnailImage", mappedBy="galleryImage")
*/
private $thumb;
/**
* @ORM\OneToOne(targetEntity="GalleryFullSizeImage", mappedBy="galleryImage")
*/
private $full;
/**
* @ORM\Column(name="lastModified", type="datetime", nullable=true)
*/
private $lastModified;
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
}
/**
* @return GalleryFullSizeImage
*/
public function getFull()
{
return $this->full;
}
/**
* @param GalleryFullSizeImage $full
*/
public function setFull(Full $full)
{
$this->full = $full;
}
/**
* @return GalleryThumbnailImage
*/
public function getThumb()
{
return $this->thumb;
}
/**
* @param GalleryThumbnailImage $thumb
*/
public function setThumb(Thumb $thumb)
{
$this->thumb = $thumb;
}
/**
* @return \DateTime
*/
public function getLastModified()
{
return $this->lastModified;
}
/**
* @param \DateTime $lastModified
*/
public function setLastModified(\DateTime $lastModified)
{
$this->lastModified = $lastModified;
}
}
// ----
/**
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
* @ORM\Table(name="GalleryFullSizeImage", indexes={@ORM\Index(name="id_idx", columns={"id"})})
*/
class GalleryFullSizeImage
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\OneToOne(targetEntity="GalleryImage", inversedBy="full")
* @ORM\JoinColumn(name="galleryImageId", referencedColumnName="id", onDelete="SET NULL")
*/
private $galleryImage;
/**
* @ORM\Column(type="string", length=255)
*/
private $path;
/**
* @Assert\Image(maxSize="6000000")
*/
private $file;
private $tmp;
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
}
public function getGalleryImage()
{
return $this->galleryImage;
}
public function setGalleryImage(GalleryImage $galleryImage)
{
$this->galleryImage = $galleryImage;
}
public function getWebPath()
{
return null === $this->path ? null : $this->getUploadRootDir() . '/' . $this->path;
}
protected function getUploadRootDir()
{
// the absolute directory path where uploaded
// documents should be saved
return __DIR__ . '/../../../../web/' . $this->getUploadDir() . '/full';
}
protected function getUploadDir()
{
// get rid of the __DIR__ so it doesn't screw up
// when displaying uploaded doc/image in the view.
return 'uploads/gallery';
}
/**
* Sets file.
*
* @param UploadedFile $file
*/
public function setFile(UploadedFile $file = null)
{
$this->file = $file;
// check if we have an old image path
if (is_file($this->getAbsolutePath())) {
// store the old name to delete after the update
$this->tmp = $this->getAbsolutePath();
} else {
$this->path = 'initial';
}
}
/**
* Returns file
*
* @return mixed
*/
public function getFile()
{
return $this->file;
}
/**
* @ORM\PrePersist()
* @ORM\PreUpdate()
*/
public function preUpload()
{
if (null !== $this->getFile()) {
$this->path = $this->getFile()->guessExtension();
}
}
/**
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function upload()
{
if (null === $this->getFile()) {
return;
}
// check if we have an old image
if (isset($this->tmp)) {
// delete the old image
unlink($this->tmp);
// clear the temp image path
$this->tmp = null;
}
$this->getFile()->move(
$this->getUploadRootDir(),
$this->id . '.' . $this->getFile()->guessExtension()
);
$this->setFile(null);
$this->galleryImage->setLastModified(new \DateTime(null));
}
/**
* @ORM\PreRemove()
*/
public function storeFilenameForRemove()
{
$this->tmp = $this->getAbsolutePath();
}
/**
* @ORM\PostRemove()
*/
public function removeUpload()
{
if (isset($this->tmp)) {
unlink($this->tmp);
$this->galleryImage->setLastModified(new \DateTime(null));
}
}
public function getAbsolutePath()
{
return null === $this->path ? null : $this->getUploadRootDir() . '/' . $this->id . '.' . $this->path;
}
}
// ----
/**
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
* @ORM\Table(name="GalleryThumbnailImage", indexes={@ORM\Index(name="id_idx", columns={"id"})})
*/
class GalleryThumbnailImage
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\OneToOne(targetEntity="GalleryImage", inversedBy="thumb")
* @ORM\JoinColumn(name="galleryImageId", referencedColumnName="id", onDelete="SET NULL")
*/
private $galleryImage;
/**
* @ORM\Column(type="string", length=255)
*/
private $path;
/**
* @Assert\Image(maxSize="6000000")
*/
private $file;
private $tmp;
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
}
public function getGalleryImage()
{
return $this->galleryImage;
}
public function setGalleryImage(GalleryImage $galleryImage)
{
$this->galleryImage = $galleryImage;
}
public function getWebPath()
{
return null === $this->path ? null : $this->getUploadRootDir() . '/' . $this->path;
}
protected function getUploadRootDir()
{
// the absolute directory path where uploaded
// documents should be saved
return __DIR__ . '/../../../../web/' . $this->getUploadDir() . '/thumbs';
}
protected function getUploadDir()
{
// get rid of the __DIR__ so it doesn't screw up
// when displaying uploaded doc/image in the view.
return 'uploads/gallery';
}
/**
* Sets file.
*
* @param UploadedFile $file
*/
public function setFile(UploadedFile $file = null)
{
$this->file = $file;
// check if we have an old image path
if (is_file($this->getAbsolutePath())) {
// store the old name to delete after the update
$this->tmp = $this->getAbsolutePath();
} else {
$this->path = 'initial';
}
}
/**
* Returns file
*
* @return mixed
*/
public function getFile()
{
return $this->file;
}
/**
* @ORM\PrePersist()
* @ORM\PreUpdate()
*/
public function preUpload()
{
if (null !== $this->getFile()) {
$this->path = $this->getFile()->guessExtension();
}
}
/**
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function upload()
{
if (null === $this->getFile()) {
return;
}
// check if we have an old image
if (isset($this->tmp)) {
// delete the old image
unlink($this->tmp);
// clear the temp image path
$this->tmp = null;
}
$this->getFile()->move(
$this->getUploadRootDir(),
$this->id . '.' . $this->getFile()->guessExtension()
);
$this->setFile(null);
$this->galleryImage->setLastModified(new \DateTime(null));
}
/**
* @ORM\PreRemove()
*/
public function storeFilenameForRemove()
{
$this->tmp = $this->getAbsolutePath();
}
/**
* @ORM\PostRemove()
*/
public function removeUpload()
{
if (isset($this->tmp)) {
unlink($this->tmp);
$this->galleryImage->setLastModified(new \DateTime(null));
}
}
public function getAbsolutePath()
{
return null === $this->path ? null : $this->getUploadRootDir() . '/' . $this->id . '.' . $this->path;
}
}
当我尝试查看表单本身时,我从UnexpectedTypeException
收到以下错误消息:
类型"字符串或Symfony \ Component \ Form \ FormTypeInterface"," MajorProductions \ SewingDiva \ SiteBundle \ Entity \ GalleryThumbnailImage"的预期参数给出
所以,它FormBuilder
添加了我的GalleryThumbnailImage
字段,认为它应该由字符串而不是该对象支持。但是,我真的不知道为什么会这样做。可能是因为我在GalleryImage
中使用了命名空间别名(Thumb
代替GalleryThumbnailImage
而Full
代替GalleryFullSizeImage
)?或者我错过了一些明显的东西?
编辑:在为GalleryFullSizeImage
和GalleryThumbnailImage
创建表单类型后问题仍然存在:
namespace MajorProductions\SewingDiva\SiteBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class GalleryFullSizeImageType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('file', 'file');
}
public function getName()
{
return 'galleryFullSizeImage';
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array('data_class' => 'MajorProductions\SewingDiva\SiteBundle\Entity\GalleryFullSizeImage'));
}
}
// ----
namespace MajorProductions\SewingDiva\SiteBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class GalleryThumbnailImageType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('file', 'file');
}
public function getName()
{
return 'galleryThumbnailImage';
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array('data_class' => 'MajorProductions\SewingDiva\SiteBundle\Entity\GalleryThumbnailImage'));
}
}
请注意,在我的代码中写入// ----
,表示一个文件的结尾和另一个文件的开头。给定我的实体代码的长度以及所有Doctrine注释,我想通过将各个类的代码放在相同的代码块中来节省一些垂直空间。
答案 0 :(得分:1)
您使用:
$builder
->add('thumb', new GalleryThumbnailImage(), array('label' => 'Thumbnail Image'))
->add('full', new GalleryFullSizeImage(), array('label' => 'Full Size Image'));
让我们回想一下FormBuilder#add()
的论点:public function add($child, $type = null, array $options = array())
。您似乎传递了一个实体,而不是$type
。您要在此处传递的课程为GalleryThumbnailImageType
和GalleryFullSizeImageType
。这些类确实实现了FormTypeInterface
,所以一切正常!
您需要使用的代码:
$builder
->add('thumb', new GalleryThumbnailImageType(), array('label' => 'Thumbnail Image'))
->add('full', new GalleryFullSizeImageType(), array('label' => 'Full Size Image'));