使用symfony2和文件上载生成多个(oneToMany)实体

时间:2014-05-04 12:15:38

标签: php forms symfony one-to-many

我遇到了与我正在构建的Symfony2应用程序相关的问题。问题涉及链接到一张或多张图片的文章(新闻)(插图)。看起来很简单。但我在控制器上堆叠,应该保留新闻,插图和上传图片文件。

我的新闻表单类型:

namespace Fcbg\NewsBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;

class NewsType extends AbstractType
{
    public function buildForm( FormBuilderInterface $builder, array $options )
    {
        $builder
            ->add('date', 'date')
            ->add('titre', 'text')
            ->add('contenu', 'textarea')
            ->add('publication', 'checkbox', array('required' => false))
            ->add('type', 'entity', array( 'class' => 'FcbgNewsBundle:Illustration', 'property' => 'value', 'multiple' => true ));
    }

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

我的图片表单类型:

namespace Fcbg\NewsBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class IllustrationType extends AbstractType
{
    public function buildForm( FormBuilderInterface $builder, array $options )
    {
        $builder
            ->add('file', 'file');
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Fcbg\NewsBundle\Entity\Illustration',
            'cascade_validation' => true,
        ));
    }
    public function getName()
    {
        return 'News';
    }
}

我的控制器操作:

public function addAction()
    {
       //link works properly I think
       $news = new News();
       $illustration = new Illustration();
       $illustration->setNews($news);
       $news->addIllustration($illustration);

       $form = $this->createForm(new NewsType(), $news);
       $request = $this->get('request');

       if ($request->getMethod() == 'POST') {
          $form->bind($request);
          if ($form->isValid()) {
             $doctrine = $this->getDoctrine();
             $newsManager = $doctrine->getManager();

             $newsManager->persist($news);
             $newsManager->persist($illustration);
             $newsManager->flush();

             return $this->redirect(...);
          }
        }

        return $this->render('base.html.twig', 
            array(
                'content' => 'FcbgNewsBundle:Default:formulaireNews.html.twig',
                'form' =>  $form->createView(),
                'name' => "add a news"
            )
        );  
    }

执行错误:

Entities passed to the choice field must be managed. Maybe persist them in the entity manager?

这里的问题是我的实体获得了一个名为" getIllustrations()"的方法。它在逻辑上返回了插图的arrey。所以我无法理解这个错误/问题。我假设我的"插图应该是文件字段而不是选择字段......

关于我如何能走得更远的任何想法?很多!

2 个答案:

答案 0 :(得分:0)

我认为问题在于您正在使用'实体'表格字段:

->add('type', 'entity', array( 'class' => 'FcbgNewsBundle:Illustration', 'property' => 'value', 'multiple' => true ));

这种类型的表单字段作为选择,它用于处理在数据库中创建的元素。您可以在http://symfony.com/doc/current/reference/forms/types/entity.html

中看到这一点

可能的解决方案是使用"原型"像这里http://symfony.com/doc/current/cookbook/form/form_collections.html#cookbook-form-collections-new-prototype

你可以在哪里:

public function buildForm( FormBuilderInterface $builder, array $options )
{
    $builder
        ->add('date', 'date')
        ->add('titre', 'text')
        ->add('contenu', 'textarea')
        ->add('publication', 'checkbox', array('required' => false))
        ->add('type', 'collection', array(
            'type'         => new IllustrationType(),
            'allow_add'    => true,
    ));
}

我希望这对你有用。

亲切的问候。

答案 1 :(得分:0)

所以,我正在谈论的代码:

public function buildForm( FormBuilderInterface $builder, array $options )
    {
        $builder
            ->add('date', 'date')
            ->add('titre', 'text')
            ->add('contenu', 'textarea')
            ->add('publication', 'checkbox', array('required' => false))
            ->add('illustrations', 'collection', array(
                'type' => new IllustrationType(), 
                'allow_add' => true 
            ));
    }