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