Forms ZF2和Doctrine2:一种形式->;两个实体

Forms ZF2和Doctrine2:一种形式->;两个实体,forms,doctrine-orm,zend-framework2,Forms,Doctrine Orm,Zend Framework2,我想制作一个表单,在这个表单中,我可以使用元素填充两个实体。 我该怎么做?其中一个对象映射到另一个对象。 例如,我有这样的东西: 表用户: id | login | password 表用户电子邮件: id | user_id | email 可以有多行用户电子邮件映射到用户-用户可以有多个电子邮件。 但是-当我添加第一次出现的用户时,我必须收到他的第一封电子邮件 我知道如何映射实体的一切,但我在从ZF2表单填充对象方面有问题 谁能建议我怎么做?我试图创建两个字段集,但无法将对象绑定到字段

我想制作一个表单,在这个表单中,我可以使用元素填充两个实体。 我该怎么做?其中一个对象映射到另一个对象。 例如,我有这样的东西:

表用户:

id | login | password
表用户电子邮件:

id | user_id | email 
可以有多行用户电子邮件映射到用户-用户可以有多个电子邮件。 但是-当我添加第一次出现的用户时,我必须收到他的第一封电子邮件

我知道如何映射实体的一切,但我在从ZF2表单填充对象方面有问题

谁能建议我怎么做?我试图创建两个字段集,但无法将对象绑定到字段集。如果这是解决方案,如何将对象绑定到具有两个文件集的表单?每个字段集都映射了doctrine2或doctrine2,但当我试图将其中一个实体绑定到表单时(不是我无法执行的字段集),我收到错误消息:

Zend\Stdlib\Hydrator\ArraySerializable::extract expects the provided object to implement getArrayCopy()
在我举例之前,我必须解释我想要达到的目标。我有一个表摄像头-其中包含链接和一些关于流媒体摄像头的其他信息。第二个表:cameras_desc包含用不同语言对这些摄像头的描述。在我的CMS中,我想添加两行:一行在cameras中,另一行在CMeras_desc中,以一种形式。cameras_desc将首次翻译为波兰语(这将是CMS的默认语言)。正如您所见,cameras和cameras_desc与其他一些实体(带有检查点的cameras和带有语言的cameras_desc)映射。但这不是重点。我想要实现的是用一个表单填充两个表中的两行。cameras_desc中的lang由PHP代码设置,但检查点由用户以select元素的形式设置。下面的代码中的所有内容都可以工作,但它并不是真实生成的

这是我的代码:

第一实体:
namespace Granica\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Cameras
 *
 * @ORM\Table(name="cameras", indexes={@ORM\Index(name="IDX_6B5F276AF27C615F", columns={"checkpoint_id"})})
 * @ORM\Entity
 */
class Cameras
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="link", type="text", nullable=false)
     */
    private $link;

    /**
     * @var string
     *
     * @ORM\Column(name="direction", type="string", length=4, nullable=false)
     */
    private $direction;

    /**
     * @var \Granica\Entity\Checkpoints
     *
     * @ORM\ManyToOne(targetEntity="Granica\Entity\Checkpoints")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="checkpoint_id", referencedColumnName="id")
     * })
     */
    private $checkpoint;



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

    /**
     * Set link
     *
     * @param string $link
     * @return Cameras
     */
    public function setLink($link)
    {
        $this->link = $link;

        return $this;
    }

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

    /**
     * Set direction
     *
     * @param string $direction
     * @return Cameras
     */
    public function setDirection($direction)
    {
        $this->direction = $direction;

        return $this;
    }

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

    /**
     * Set checkpoint
     *
     * @param \Granica\Entity\Checkpoints $checkpoint
     * @return Cameras
     */
    public function setCheckpoint(\Granica\Entity\Checkpoints $checkpoint = null)
    {
        $this->checkpoint = $checkpoint;

        return $this;
    }

    /**
     * Get checkpoint
     *
     * @return \Granica\Entity\Checkpoints 
     */
    public function getCheckpoint()
    {
        return $this->checkpoint;
    }
}
第二实体:

<?php

namespace Granica\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * CamerasDesc
 *
 * @ORM\Table(name="camera_desc", indexes={@ORM\Index(name="lang", columns={"lang"}), @ORM\Index(name="camera_id", columns={"camera_id"})})
 * @ORM\Entity
 */
class CameraDesc
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="description", type="text", nullable=false)
     */
    private $description;

    /**
     * @var \Granica\Entity\Languages
     *
     * @ORM\ManyToOne(targetEntity="Granica\Entity\Languages")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="lang", referencedColumnName="id")
     * })
     */
    private $lang;

    /**
     * @var \Granica\Entity\Cameras
     *
     * @ORM\ManyToOne(targetEntity="Granica\Entity\Cameras")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="camera_id", referencedColumnName="id")
     * })
     */
    private $camera;



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

    /**
     * Set description
     *
     * @param string $description
     * @return CamerasDesc
     */
    public function setDescription($description)
    {
        $this->description = $description;

        return $this;
    }

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

    /**
     * Set lang
     *
     * @param \Granica\Entity\Languages $lang
     * @return CamerasDesc
     */
    public function setLang(\Granica\Entity\Languages $lang = null)
    {
        $this->lang = $lang;

        return $this;
    }

    /**
     * Get lang
     *
     * @return \Granica\Entity\Languages 
     */
    public function getLang()
    {
        return $this->lang;
    }

    /**
     * Set camera
     *
     * @param \Granica\Entity\Cameras $camera
     * @return CamerasDesc
     */
    public function setCamera(\Granica\Entity\Cameras $camera = null)
    {
        $this->camera = $camera;

        return $this;
    }

    /**
     * Get camera
     *
     * @return \Granica\Entity\Cameras 
     */
    public function getCamera()
    {
        return $this->camera;
    }
}
表格(适用于相机): 和添加控制器:

public function addAction()
{
    $camera = new Cameras();
    $cameraDesc = new CameraDesc();
    $lang = $this->getEntityManager()->getRepository('Granica\Entity\Languages')->find('pl');

    $form = new AddCameraForm($this->getEntityManager());
    $cameraDescFieldset = new CameraDescFieldset($this->getEntityManager());

    $form->setHydrator(new DoctrineHydrator($this->getEntityManager(),'Granica\Entity\Cameras'));

    $form->bind($camera);

    $request = $this->getRequest();
    if ($request->isPost()) {
        $form->setData($request->getPost());
        if ($form->isValid()) {
            $data = $form->getData(); 
            $cameraDesc->setLang($lang);
            $cameraDesc->setDescription($request->getPost()['camera_desc']['description']);

            $this->getEntityManager()->persist($camera);            

            $cameraDesc->setCamera($camera);            

            $this->getEntityManager()->persist($cameraDesc);            
            $this->getEntityManager()->flush();

            return $this->redirect()->toRoute('cameras');
        }
    }

    return new ViewModel(array('form' => $form));
}  

正如你们所看到的,我已经设法克服了我的问题——我已经用我从post获得的数据填充了camera_desc。这是可行的,但不是最好的解决方案-例如,过滤器在cameraDesc描述上不起作用。

好的,我做了一些更改,现在当我将实体绑定到表单(其中有存储其他数据的字段集)时,我无法获取此数据$form->getData()只返回绑定对象,但如何获取字段集数据?能否添加一个表单和字段集的示例,以便我们了解您的示例。如果没有,请看一看:如果我没有弄错的话,这可能会是你的问题。您可能需要使用两个字段集,因为每个字段集或表单只能绑定到一个对象/实体。看一看。谢谢。也许我应该在fieldset对象上使用setObject方法?它的工作原理是否与表单上的bind方法相同?我目前无法向您提供示例,因此我希望您观看:它将解释水合器如何使用ZF2表单和字段集,并为您提供一个很好的示例,说明如何将其与示例一起使用。您确实应该使用
setObject(新实体)
,这样
or
就知道需要使用哪个对象。
use Zend\Form\Form;

use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use Doctrine\Common\Persistence\ObjectManager;

use Granica\Form\CameraDescFieldset;

class AddCameraForm extends Form implements ObjectManagerAwareInterface
{
    protected $objectManager;
    public function __construct(ObjectManager $objectManager)
    {       
        parent::__construct('checkpoint');
        $this->setObjectManager($objectManager);

        // tworzenie formularza
        $this->setAttribute('method', 'post');

        $this->add(array(
            'name'    => 'checkpoint',
            'type'    => 'DoctrineModule\Form\Element\ObjectSelect',
            'options' => array(
                'label'          => 'Punkt graniczny',
                'object_manager' => $this->getObjectManager(),
                'target_class'   => 'Granica\Entity\Checkpoints',
                'property'       => 'name',
                'empty_option'   => '--- wybierz przejście ---'
            ),
        ));

        $this->add(array(
            'name' => 'link',
            'attributes' => array(
                'type'  => 'text',
                'placeholder' => 'Link',
                'required' => 'true',
            ),
            'options' => array(
                'label' => 'Adres URL kamery',
            ),
        ));

        $this->add(array(
            'type' => 'Zend\Form\Element\Select',
            'name' => 'direction',
            'attributes' => array(
                'required' => 'true',
            ),
            'options' => array(
                'label' => 'Kierunek',
                'empty_option' => '--- wybierz kierunek ---',
                'value_options' => array(
                    'from' => 'FROM: Wyjazd z Polski',
                    'to' =>   'TO:   Wjazd do Polski',
                ),
            )
        ));               

        $this->add(new CameraDescFieldset($this->getObjectManager()));

        $this->add(array(
            'name' => 'submit',
            'attributes' => array(
                'type'  => 'submit',
                'value' => 'Zapisz',
                'id' => 'submitbutton',
            ),
        )); 
    }

    // implementacja interfajsu objectmanager
    public function setObjectManager(ObjectManager $objectManager)
    {
        $this->objectManager = $objectManager;
        return $this;
    }

    public function getObjectManager()
    {
        return $this->objectManager;
    }       

}
public function addAction()
{
    $camera = new Cameras();
    $cameraDesc = new CameraDesc();
    $lang = $this->getEntityManager()->getRepository('Granica\Entity\Languages')->find('pl');

    $form = new AddCameraForm($this->getEntityManager());
    $cameraDescFieldset = new CameraDescFieldset($this->getEntityManager());

    $form->setHydrator(new DoctrineHydrator($this->getEntityManager(),'Granica\Entity\Cameras'));

    $form->bind($camera);

    $request = $this->getRequest();
    if ($request->isPost()) {
        $form->setData($request->getPost());
        if ($form->isValid()) {
            $data = $form->getData(); 
            $cameraDesc->setLang($lang);
            $cameraDesc->setDescription($request->getPost()['camera_desc']['description']);

            $this->getEntityManager()->persist($camera);            

            $cameraDesc->setCamera($camera);            

            $this->getEntityManager()->persist($cameraDesc);            
            $this->getEntityManager()->flush();

            return $this->redirect()->toRoute('cameras');
        }
    }

    return new ViewModel(array('form' => $form));
}