嵌入Symfony文件表单

时间:2015-02-25 03:15:09

标签: php forms symfony

我想在Symfony中将表单(ImageType)嵌入到另一个表单(VideoFileType)中。我的第一个表单包含文件输入。基本上,它是根据已经定义的许多预设上传然后调整大小的图像。

我的第二个表单将嵌入ImageType表单。第二种形式是VideoFileType形式,其中包含ImageType形式。基本上,ImageType将充当视频文件的缩略图。 VideoFileType还将包含第二个文件输入以上传videoFile,最后还有一个选择框以选择相应的VideoPreset。

回顾一下,VideoFileType会嵌入ImageType

我的班级结构很相似。我有一个VideoFile,其Thumbnail属性为Image

当我只显示ImageType并上传图片时,一切正常。

将ImageType

class ImageType extends AbstractType
{
    private $imageManager;

    public function __construct(ImageManager $imageManager) {
        $this->imageManager = $imageManager;
    }


    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('file', 'file');

        $builder->addEventListener(
            FormEvents::POST_SUBMIT,
            array($this, 'onPostSetData')
        );
    }

    public function getDefaultOptions(array $options) {
        return array('data_class' => 'OSC\MediaBundle\Entity\Image');
    }

    public function onPostSetData(FormEvent $event) {
        $image = $event->getData();
        $form = $event->getForm();

        //We need here to update the video file with the new content
        $image = $this->imageManager->uploadImage($image);
        $event->setData($image);

    }

    public function getName()
    {
        return 'image';
    }
}

VideoFileType

class VideoFileType extends AbstractType
{

    public $container;

    public $videoPresets = [];

    public function __construct(Container $container) {
        $this->container = $container;
        $videoPresets = $container->getParameter('osc_media.video.presets');
        foreach ($videoPresets as $key => $videoPreset) {
            array_push($this->videoPresets, $key);
        }

    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('thumbnail', new ImageType($this->container->get('osc_media.manager.image')));
        $builder->add('file', 'file');
        $builder->add('videoPreset', 'choice', array(
            'choices' => $this->videoPresets,
            'multiple' => false,
            'required' => true
        ));
        $builder->addEventListener(
            FormEvents::POST_SUBMIT,
            array($this, 'onPostSetData')
        );
        $builder->add('save', 'submit');
    }

    public function onPostSetData(FormEvent $event) {
        $videoFile = $event->getData();
        $form = $event->getForm();

    }


    public function getDefaultOptions(array $options) {
        return array('data_class' => 'OSC\MediaBundle\Entity\VideoFile');
    }

    public function getName()
    {
        return 'video_file';
    }
}

录像档案

class VideoFile
{

    protected $file;

    public function setfile(File $file = null)
    {
        $this->file = $file;

        if ($file) {
            // 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 File
     */
    public function getFile()
    {
        return $this->file;
    }

    public function __construct() {
        $this->thumbnail = new Image();
    }


    /**
     * @var integer
     */
    private $id;

    /**
     * @var string
     */
    private $name;

    /**
     * @var string
     */
    private $filename;

    /**
     * @var integer
     */
    private $position;

    /**
     * @var string
     */
    private $extension;

    /**
     * @var integer
     */
    private $size;

    /**
     * @var string
     */
    private $videoPreset;

    /**
     * @var integer
     */
    private $duration;

    /**
     * @var \DateTime
     */
    private $createdAt;

    /**
     * @var \DateTime
     */
    private $updatedAt;

    /**
     * @var string
     */
    private $height;

    /**
     * @var string
     */
    private $width;

    /**
     * @var \OSC\MediaBundle\Entity\Image
     */
    private $thumbnail;

    /**
     * @var \OSC\MediaBundle\Entity\Video
     */
    private $video;


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

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

        return $this;
    }

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

    /**
     * Set filename
     *
     * @param string $filename
     * @return VideoFile
     */
    public function setFilename($filename)
    {
        $this->filename = $filename;

        return $this;
    }

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

    /**
     * Set position
     *
     * @param integer $position
     * @return VideoFile
     */
    public function setPosition($position)
    {
        $this->position = $position;

        return $this;
    }

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

    /**
     * Set extension
     *
     * @param string $extension
     * @return VideoFile
     */
    public function setExtension($extension)
    {
        $this->extension = $extension;

        return $this;
    }

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

    /**
     * Set size
     *
     * @param integer $size
     * @return VideoFile
     */
    public function setSize($size)
    {
        $this->size = $size;

        return $this;
    }

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

    /**
     * Set videoPreset
     *
     * @param string $videoPreset
     * @return VideoFile
     */
    public function setVideoPreset($videoPreset)
    {
        $this->videoPreset = $videoPreset;

        return $this;
    }

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

    /**
     * Set duration
     *
     * @param integer $duration
     * @return VideoFile
     */
    public function setDuration($duration)
    {
        $this->duration = $duration;

        return $this;
    }

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

    /**
     * Set createdAt
     *
     * @param \DateTime $createdAt
     * @return VideoFile
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    /**
     * Get createdAt
     *
     * @return \DateTime 
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * Set updatedAt
     *
     * @param \DateTime $updatedAt
     * @return VideoFile
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }

    /**
     * Get updatedAt
     *
     * @return \DateTime 
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }

    /**
     * Set height
     *
     * @param string $height
     * @return VideoFile
     */
    public function setHeight($height)
    {
        $this->height = $height;

        return $this;
    }

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

    /**
     * Set width
     *
     * @param string $width
     * @return VideoFile
     */
    public function setWidth($width)
    {
        $this->width = $width;

        return $this;
    }

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

    /**
     * Set thumbnail
     *
     * @param \OSC\MediaBundle\Entity\Image $thumbnail
     * @return VideoFile
     */
    public function setThumbnail(\OSC\MediaBundle\Entity\Image $thumbnail = null)
    {
        $this->thumbnail = $thumbnail;

        return $this;
    }

    /**
     * Get thumbnail
     *
     * @return \OSC\MediaBundle\Entity\Image 
     */
    public function getThumbnail()
    {
        return $this->thumbnail;
    }

    /**
     * Set video
     *
     * @param \OSC\MediaBundle\Entity\Video $video
     * @return VideoFile
     */
    public function setVideo(\OSC\MediaBundle\Entity\Video $video = null)
    {
        $this->video = $video;

        return $this;
    }

    /**
     * Get video
     *
     * @return \OSC\MediaBundle\Entity\Video 
     */
    public function getVideo()
    {
        return $this->video;
    }
}

图片类

class Image
{

    protected $file;

    public function setfile(File $file = null)
    {
        $this->file = $file;

        if ($file) {
            // 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 File
     */
    public function getFile()
    {
        return $this->file;
    }



    /**
     * @var integer
     */
    private $id;

    /**
     * @var \Doctrine\Common\Collections\Collection
     */
    private $imageFiles;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->imageFiles = new \Doctrine\Common\Collections\ArrayCollection();
    }

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

    /**
     * Add imageFiles
     *
     * @param \OSC\MediaBundle\Entity\ImageFile $imageFiles
     * @return Image
     */
    public function addImageFile(\OSC\MediaBundle\Entity\ImageFile $imageFiles)
    {
        $this->imageFiles[] = $imageFiles;

        return $this;
    }

    /**
     * Remove imageFiles
     *
     * @param \OSC\MediaBundle\Entity\ImageFile $imageFiles
     */
    public function removeImageFile(\OSC\MediaBundle\Entity\ImageFile $imageFiles)
    {
        $this->imageFiles->removeElement($imageFiles);
    }

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

镜像文件

class ImageFile
{





    /**
     * @var integer
     */
    private $id;

    /**
     * @var string
     */
    private $name;

    /**
     * @var string
     */
    private $filename;

    /**
     * @var string
     */
    private $extension;

    /**
     * @var string
     */
    private $size;

    /**
     * @var string
     */
    private $imagePreset;

    /**
     * @var \DateTime
     */
    private $createdAt;

    /**
     * @var \DateTime
     */
    private $updatedAt;

    /**
     * @var string
     */
    private $height;

    /**
     * @var string
     */
    private $width;


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

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

        return $this;
    }

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

    /**
     * Set filename
     *
     * @param string $filename
     * @return ImageFile
     */
    public function setFilename($filename)
    {
        $this->filename = $filename;

        return $this;
    }

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

    /**
     * Set extension
     *
     * @param string $extension
     * @return ImageFile
     */
    public function setExtension($extension)
    {
        $this->extension = $extension;

        return $this;
    }

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

    /**
     * Set size
     *
     * @param string $size
     * @return ImageFile
     */
    public function setSize($size)
    {
        $this->size = $size;

        return $this;
    }

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

    /**
     * Set imagePreset
     *
     * @param string $imagePreset
     * @return ImageFile
     */
    public function setImagePreset($imagePreset)
    {
        $this->imagePreset = $imagePreset;

        return $this;
    }

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

    /**
     * Set createdAt
     *
     * @param \DateTime $createdAt
     * @return ImageFile
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    /**
     * Get createdAt
     *
     * @return \DateTime 
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * Set updatedAt
     *
     * @param \DateTime $updatedAt
     * @return ImageFile
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }

    /**
     * Get updatedAt
     *
     * @return \DateTime 
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }

    /**
     * Set height
     *
     * @param string $height
     * @return ImageFile
     */
    public function setHeight($height)
    {
        $this->height = $height;

        return $this;
    }

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

    /**
     * Set width
     *
     * @param string $width
     * @return ImageFile
     */
    public function setWidth($width)
    {
        $this->width = $width;

        return $this;
    }

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

但是,当我尝试创建VideoFileType表单时,出现以下错误:

The form's view data is expected to be of type scalar, array or an instance of \ArrayAccess, but is an instance of class OSC\MediaBundle\Entity\Image. You can avoid this error by setting the "data_class" option to "OSC\MediaBundle\Entity\Image" or by adding a view transformer that transforms an instance of class OSC\MediaBundle\Entity\Image to scalar, array or an instance of \ArrayAccess.

所以,我想要的是,ImageFileType(OnPostSetData)的处理在嵌入VideoFileType时与单独使用时一样成功执行。

然后,完成后,我希望Image对象作为缩略图属性插入VideoFile。之后,它应该在VideoFileType的OnPostSetData方法中完成处理。

如果它不可行,我只是在VideoFileType中重新创建ImageType的逻辑,这不是什么大问题。但是,我觉得如果我可以重用ImageFileType就可以了。

2 个答案:

答案 0 :(得分:2)

我不是100%肯定,但尝试将此功能添加到您的ImageType课程中。

use Symfony\Component\OptionsResolver\OptionsResolverInterface;
....
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'OSC\MediaBundle\Entity\Image'
    ));
}

并更改班级buildFormVideoFileType内缩略图属性的配置。

$builder->add('thumbnail', 
               new ImageType($this->container->get('osc_media.manager.image')),
               array(
                  'data_class' => 'OSC\MediaBundle\Entity\Image'
               ));

答案 1 :(得分:0)

如果你想扩展formtype,

,这很容易

就这样做:

  1. 将您的第一个表单定义为服务
  2. 使用getParent方法扩展您的第二个表单

    public function getParent() {     返回'图像'; }

  3. 这样做你在第二个表单中的字段与第一个字段相同 你可以添加更多。