doctrine2 zf2表单集合不呈现元素

时间:2014-04-18 09:46:29

标签: forms collections doctrine-orm zend-framework2 one-to-many

更新:如果我升级到2.2.6,我只会工作到ZF2的2.2.5版本,该项目不会显示在表单上。

  • ZF2 2.3.1
  • PHP 5.4.4
  • Doctrine2:Master

我遇到了bind()表单的问题。当我尝试显示Zend \ Form \ Collection字段集的元素时显示为空。

我已阅读了教程Doctrine Hydrator,但我无法修复它。

实体之间的关系非常简单:

  • 产品(OneToMany)$ images
  • 图片(ManyToOne)$ product

只有在我添加新产品时才会发生这种情况,如果我编辑带有图像的产品(动作编辑),表单上显示的FormCollection元素。

产品实体

class Product 
{

    /**
     * @var int
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     *
     */
    protected $id;

    /**
     * @var string
     * @ORM\Column(type="string", length=255, unique=false, nullable=true)
     */
    protected $name;

    /**
     * @ORM\OneToMany(targetEntity="Image", mappedBy="product", cascade={"persist"})
     */
    protected $images;

    public function __construct()    
    {
        $this->images = new ArrayCollection();    
    }

    public function addImages(Collection $images)
    {
        foreach ($images as $image)
        {
            $image->setProduct($this);
            $this->images->add($image);
        }
    }

    public function removeImages(Collection $images)
    {
        foreach ($images as $image)
        {
            $image->setProduct(null);
            $this->images->removeElement($image);
        }
    }

    public function getImages()
    {
        return $this->images;
    }

}

图片实体

class Image
{
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Product", inversedBy="images")
     * @ORM\JoinColumn(name="product_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $product;

    public function setProduct(Product $product = null)
    {
        $this->product = $product;
    }

    public function getProduct()
    {
        return $this->product;
    }
}

产品表格

class ProductForm extends Form implements InputFilterProviderInterface
{

    public function __construct($sl)
    {
        $objectManager = $sl->get('Doctrine\ORM\EntityManager');

        parent::__construct('product-form');

        $this->setAttribute('enctype', 'multipart/form-data')
             ->setAttribute('method', 'post')
             ->setHydrator(new DoctrineHydrator($objectManager));

        // Add the user fieldset, and set it as the base fieldset
        $productFieldset = new ProductFieldset($sl);
        $productFieldset->setName('product');
        $productFieldset->setUseAsBaseFieldset(true);
        $this->add($productFieldset);

        $this->add(array(
            'name' => 'submit',
            'attributes' => array(
                'type' => 'submit',
                'value' => 'Go',
                'id' => 'submitbutton',
                'class' => 'btn btn-primary'
            )
        ));


        $this->setValidationGroup(array(
            'product',
        ));
    }

产品字段集

class ProductFieldset extends Fieldset implements InputFilterProviderInterface
{

    public function __construct($sl)
    {
        $objectManager = $sl->get('Doctrine\ORM\EntityManager');

        parent::__construct('product');

        $this->setHydrator(new DoctrineHydrator($objectManager))
             ->setObject(new Product());


        $this->add(array(
            'name' => 'id',
            'type' => 'Zend\Form\Element\Hidden'
        ));

        $this->add(array(
            'type' => 'Zend\Form\Element\Collection',
            'name' => 'images',
            'options' => array(
                'count' => 1,
                'target_element' => new ImageFieldset($objectManager)
            )
        ));
   }
}

图像字段集

class ImageFieldset extends Fieldset implements InputFilterProviderInterface
{

        public function __construct($objectManager)
        {
            parent::__construct('image');


            $this->setHydrator(new DoctrineHydrator($objectManager))
                 ->setObject(new Image());

            $this->add(array(
                        'name' => 'id',
                        'type' => 'Zend\Form\Element\Hidden'
                        )
            );

            $this->add(array(
                        'name' => 'filename',
                        'type' => 'Zend\Form\Element\File',
                        'options' => array(
                            'label' => 'Photo Upload',
                            'label_attributes' => array(
                                'class' => 'form-label'
                            ),
                            'multiple' => true,
                            'id' => 'filename'
                        )
                    )
            );
        }

        public function getInputFilterSpecification()
            {
                return array(
                   'id' => array(
                        'required' => false
                    ),
                   'filename' => array(
                        'required'    => true,
                    )
                );
        }
    }

控制器

public function addAction()
{

        $sl = $this->getServiceLocator();

        $form = new ProductForm($sl);

        $product = new Product();

        $form->bind($product);

        if ($request->isPost()):
              ....
        endif;

        return array('form' => $form);

}

2 个答案:

答案 0 :(得分:0)

也许本教程可以提供帮助 - 它是最新的: Inject DoctrineORM EntityManager in ZF2 Form

它使用formElementManager和objectManager意识。

在init()方法中添加元素非常重要,而不是构造函数。

还请查看 Michael 所述的评论:

  

我刚刚发现在最新版本的ZF2(我这里有2.2.5)中,不再需要通过模块配置传递entityManager了。   您只需在表单类中实现“ObjectManagerAwareInterface”(以及所需的getter + setter),您就可以通过$ this-> getObjetManager()进行访问。

答案 1 :(得分:0)

也许你正面临这个问题: BC break in forms between 2.3.0 and 2.3.1

  

在2.3.0和2.3.1之间的Zend \ Form中,我们刚刚升级并偶然发现它。   我们通过FormElementManager获取表单的实例,因为我们使用自定义表单元素,该站点一直使用&lt; = 2.3.0但在2.3.1升级之后,当我们获取表单实例时,它们不再附加任何元素。< / p>

使用FormElementManager时的一些常规更改: Creating custom elements

To use custom elements with the FormElementManager needs a bit more work and most likely a change in how you write and use your forms.