【问题标题】:ZF2 form removing nested collection after validationZF2 表单在验证后删除嵌套集合
【发布时间】:2016-10-30 16:04:23
【问题描述】:

我尝试将三个相关的 Doctrine 实体与 Zend Form 集合一起使用。

实体是 InvoiceItems ->(一对多)-> InvoiceItemOptions ->(一对多)InvoiceItemOptionValues。

当我添加一个新项目时,所有选项和值都会正确填充实体。但是,当我编辑一个项目时,值将从选项实体中删除。表单正确显示,因此从数据库中提取值并且 DoctrineObject hydrator 正在填充表单。验证表单后,这些值将丢失。

我的实体代码

发票项目

/**
 * @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,
        ),
    ));
}

编辑项目模型

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 版

希望有人知道这里发生了什么,非常感谢。

【问题讨论】:

    标签: doctrine-orm zend-framework2 zend-form


    【解决方案1】:

    我找到了解决办法。

    在表单验证之前添加行$this-&gt;form-&gt;setBindOnValidate(FormInterface::BIND_MANUAL); 解决了问题。验证后我还加了$this-&gt;form-&gt;bind($this-&gt;entity);

    希望这对某人有所帮助。

    编辑

    我还发现 InvoiceItemOptions 实体中的值的数组集合在水合期间没有被克隆,因此 InvoiceItemOptionValues 是错误的。我通过向我的 InvoiceItemOptions 实体添加魔术方法 __clone() 解决了这个问题。

    public function __clone()
    {
        $this->values = new ArrayCollection();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-06
      • 2020-11-26
      • 2018-10-10
      • 2016-03-15
      相关资源
      最近更新 更多