我有三个与Zend Form集合一起使用的相关Doctrine实体。
实体是InvoiceItems - > (一对多) - > InvoiceItemOptions - > (一对多)InvoiceItemOptionValues。
当我添加新项目时,所有选项和值都正确填充实体。但是,当我编辑项目时,值将从选项实体中删除。表单正确显示,以便从数据库中提取值,并且DoctrineObject水合器填充表单。验证表单后,这些值将丢失。
我的实体代码
InvoiceItems
/**
* @var \Doctrine\ORM\PersistentCollection
*
* @ORM\OneToMany(targetEntity="Application\Entity\InvoiceItemOptions", cascade={"persist"}, orphanRemoval=true, mappedBy="invoiceItem")
* })
*/
private $options;
InvoiceItemOptions
/**
* @var \Application\Entity\InvoiceItems
*
* @ORM\ManyToOne(targetEntity="Application\Entity\InvoiceItems", cascade={"persist"}, inversedBy="options")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="invoice_item_id", referencedColumnName="invoice_item_id")
* })
*/
private $invoiceItem;
/**
* @var \Doctrine\ORM\PersistentCollection $values
*
* @ORM\OneToMany(targetEntity="Application\Entity\InvoiceItemOptionValues", cascade={"persist"}, orphanRemoval=true, mappedBy="invoiceItemOption")
* })
*/
private $values;
InvoiceItemOptionValues
/**
* @var integer
*
* @ORM\Column(name="invoice_item_option_value_id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $invoiceItemOptionValueId;
/**
* @var \Application\Entity\InvoiceItemOptions
*
* @ORM\ManyToOne(targetEntity="Application\Entity\InvoiceItemOptions", cascade={"persist"}, inversedBy="values")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="invoice_item_option_id", referencedColumnName="invoice_item_option_id")
* })
*/
private $invoiceItemOption;
/**
* @var string
*
* @ORM\Column(name="value", type="text", length=65536, nullable=false)
*/
private $value;
/**
* @var string
*
* @ORM\Column(name="price", type="decimal", precision=9, scale=2, nullable=false)
*/
private $price;
在我的田野中我有
InvoiceItemFieldset
$this->add(array(
'type' => 'Collection',
'name' => 'options',
'options' => array(
'count' => 0,
'should_create_template' => TRUE,
'template_placeholder' => '__OPTION__',
'allow_add' => TRUE,
'allow_remove' => TRUE,
'target_element' => $this->invoiceItemOptionFieldset,
),
));
InvoiceItemOptionFieldset
$this->add(array(
'type' => 'Collection',
'name' => 'values',
'options' => array(
'count' => 0,
'should_create_template' => TRUE,
'template_placeholder' => '__VALUE__',
'target_element' => $this->invoiceItemOptionValuesFieldset,
),
));
InvoiceItemOptionValuesFieldset
public function init()
{
$this->add(array(
'name' => 'invoiceItemOptionValueId',
'type' => 'Hidden'
));
$this->add(array(
'name' => 'value',
'type' => 'Textarea',
'options' => array(
'label' => _('Value:'),
'label_attributes' => array('class' => 'required'),
),
'attributes' => array(
'cols' => 30,
'rows' => 5,
),
));
$this->add(array(
'name' => 'price',
'type' => 'Text',
'options' => array(
'label' => _('Price Inc. VAT:'),
),
'attributes' => array(
'size' => 10,
'maxlength' => 10,
),
));
}
EditItemModel
use Zend\Stdlib\Parameters;
...
public function processForm(Parameters $postData)
{
$entityManager = $this->getEntityManager();
$this->form->setData($postData);
if ($this->form->isValid()) {
// values lost here
$this->form->bind($this->entity);
$this->setFormValid(TRUE);
if ($this->entity->getQuantity() < 1) {
$this->entity->setQuantity(1);
}
$goodsTotal = $this->entity->getPriceEachIncVat() * $this->entity->getQuantity();
$optionsTotal = 0.00;
foreach ($this->entity->getOptions() as $option) {
foreach ($option->getValues() as $value) { // entity has no values
if ($value->getPrice() > 0) {
$optionsTotal = $optionsTotal + ($value->getPrice() * $this->entity->getQuantity());
}
}
}
$this->invoiceModel->calculateItemsVat($this->entity, $goodsTotal, $optionsTotal);
$entityManager->persist($this->entity);
if ($this->flushEntityManager($entityManager)) {
return $this->invoiceModel->calculateInvoiceTotals($this->getInvoice()->getInvoiceId());
}
}
return FALSE;
}
最后我的帖子数据
Array
(
[items] => Array
(
[options] => Array
(
[0] => Array
(
[name] => Test Option 0
[invoiceItemOptionId] => 37
[values] => Array
(
[0] => Array
(
[value] => Test Option 0 Value 0
[price] => 0.00
[invoiceItemOptionValueId] => 37
)
[1] => Array
(
[value] => Test Option 0 Value 1
[price] => 29.99
[invoiceItemOptionValueId] => 38
)
)
)
)
[title] => Title
[sku] =>
[quantity] => 2
[priceEachIncVat] => 1000.00
[vatRate] => 1
[invoiceItemId] => 20
)
)
我正在使用Zend Framework版本2.5.1和Doctrine ORM模块版本1.0.0
希望有人知道这里发生了什么,非常感谢提前。
答案 0 :(得分:0)
我找到了解决方案。
在表单验证之前添加行$this->form->setBindOnValidate(FormInterface::BIND_MANUAL);
解决了这个问题。我还在验证后添加了$this->form->bind($this->entity)
;
希望这有助于某人。
修改
我还发现InvoiceItemOptions实体中的值的数组集合在水合期间没有被克隆,因此InvoiceItemOptionValues是错误的。我通过将魔术方法__clone()添加到我的InvoiceItemOptions实体来解决了这个问题。
public function __clone()
{
$this->values = new ArrayCollection();
}