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

时间:2014-07-23 13:07:13

标签: forms doctrine-orm zend-framework2

我想制作一个表单,其中我可以使用元素来填充两个实体。 我怎样才能做到这一点?其中一个对象映射到另一个对象。 例如,我有这样的事情:

表用户:

id | login | password

表user_email:

id | user_id | email 

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

我知道如何映射实体,但是我从ZF2表格填充对象时遇到问题。

有谁能建议我该怎么做?我试图制作两个字段集,但我不能将对象绑定到fieldset。如果这是解决方案如何绑定对象形成哪个有两个文件集?每个fieldset都映射了doctrine2 hydrator,但是当我试图将一个实体绑定到form(而不是我不能做的fieldset)时,我有错误信息:

Zend\Stdlib\Hydrator\ArraySerializable::extract expects the provided object to implement getArrayCopy()

在我的例子之前,我必须解释我想要实现的目标。我有一个桌面摄像头 - 其中包含有关流媒体摄像头的链接和其他一些信息。第二个表:cameras_desc包含对不同语言的摄像机的描述。在我的CMS中,我想添加两行:一行在相机中,第二行在cmaeras_desc中以一种形式添加。 cameras_desc将首先使用波兰语进行翻译(这将是CMS的默认语言)。你可以看到摄像机和cameras_desc映射到其他一些entites(带检查点的摄像机和带语言的cameras_desc)。但那不是重点。我想要实现的是通过一个表单在两个表中填充两行。 cameras_desc中的lang由PHP代码设置,但是checkpoint由用户在表单中由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;
    }
}

Fieldset(适用于camera_desc):     

namespace Granica\Form;

use Zend\Form\Fieldset;

use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use DoctrineORMModule\Stdlib\Hydrator\DoctrineEntity;

use Granica\Entity\Languages;

class CameraDescFieldset extends Fieldset implements ObjectManagerAwareInterface
{
    protected $objectManager;
    public function __construct(ObjectManager $objectManager)
    {
        parent::__construct('camera_desc');
        $this->setObjectManager($objectManager);
        $this->setHydrator(new DoctrineHydrator($this->getObjectManager(),'Granica\Entity\CameraDesc'));        

        $this->add(array(
            'name' => 'description',
            'attributes' => array(
                'type'  => 'text',
                'placeholder' => 'Opis',
                'required' => 'true',
            ),
            'options' => array(
                'label' => 'Opis kamery',
            ),
        ));

    }

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

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

}

表格(相机):     

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

正如你所看到的,我已经设法克服了我的问题 - 我已经使用我从帖子中获得的数据填充了camera_desc。这项工作,但不是最好的解决方案 - 例如过滤器不适用于cameraDesc descrition。

0 个答案:

没有答案