dswqw66280 2014-11-07 22:56
浏览 65
已采纳

Symfony 2.5.6 - 在自定义表单类型中抛出UnexpectedTypeException

I have the following form type:

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'));
    }
}

And the following entities:

/**
 * @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;
    }
}

And when I attempt to view the form itself, I get the following error message from an UnexpectedTypeException:

Expected argument of type "string or Symfony\Component\Form\FormTypeInterface", "MajorProductions\SewingDiva\SiteBundle\Entity\GalleryThumbnailImage" given

So, it's choking on the FormBuilder addition of my GalleryThumbnailImage field, thinking it should be backed by a string rather than that object. I really don't know why it's doing that, however. Could it be because I used namespace aliases in GalleryImage (Thumb in place of GalleryThumbnailImage and Full in place of GalleryFullSizeImage)? Or am I missing something obvious?


EDIT: The problem remains even after creating form types for GalleryFullSizeImage and 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'));
    }
}

Note that where // ---- is written in my code, that represents the end of one file and the beginning of another. Given the length of my entity code with all of the Doctrine annotations, I figured I'd save some vertical space by putting the code of individual classes in the same code blocks here.

  • 写回答

1条回答 默认 最新

      报告相同问题?

      悬赏问题

      • ¥15 关于#大数据#的问题:请问有人能系统得总结一下什么数据分析师,数据架构师还有开发师的具体职业要求和就业前景嘛d(ŐдŐ๑)
      • ¥15 win10账户不见了怎么找回
      • ¥15 如何显示得分大于0.5的检测框
      • ¥15 微信小游戏使用云开发的CDN配置
      • ¥15 Matlab的SAW模态耦合模型的仿真程序
      • ¥20 求个C# SSL socket的客户端和 服务端代码
      • ¥15 大家调试TI C2000系列DSP用什么上位机?
      • ¥20 Eltable 如何实现鼠标拖拽范围多选
      • ¥15 产品需要了解什么代码技术才能更好站在开发角度思考问题?
      • ¥15 统计数据能提前统计吗