ZF2 + Doctrine 2:通过 ZF2 Form Hydrate 相关对象

ZF2 + Doctrine 2: Hydrate related objects via ZF2 Form

我们的应用程序(Zend Framework 2 + Doctrine 2)有一个 Order 实体,它引用它的相关对象,如 BillingAddress 等等。我们已经实施了 REST API 来创建和更新订单。数据作为关联数组传递给这个 API 并且引用对象的数据可以封装在这个数组中。即 Order API 收到的数据看起来像这样

$data = [
    // This is an attribute of the Order entity itself
    'remarks' => 'Urgent order', 
    // This is the data of the referenced BillingAddress
    'billing_address' => [
        'firstname' => 'Barry',
        'lastname' => 'Fooman'
    ]
];

首先要注意的是给定的 BillingAddress 可以是新的也可以是现有的!在后一种情况下,id 将成为 billing_address 数据的一部分。

使用 DoctrineObject 保湿器

$hydrator = new DoctrineObject($entityManager);
$hydrator->hydrate($order, $data);

Doctrine 负责自动更新或创建引用的对象。到目前为止,我们是这样做的:获取接收到的数据,进行一些处理以清理和验证数据,然后调用 hydrator。

但是我们现在想使用 Zend\Form\Form 来轻松清理接收到的数据。为 Order 的简单属性设置一个 Form 非常容易

class OrderForm
    extends \Zend\Form\Form
{
    public function __construct()
    {
        parent::__construct('order');

        $this
            ->add([
                'name' => 'remarks',
                'type' => 'text'
            ]);
    }
}

但我对引用的对象感到困惑。我如何设置表单,以便像直接使用 hydrator 一样由 Doctrine 创建或更新引用的对象?我必须创建一个 "sub-form/fieldset" 吗?

是的,您可以为 BusinessAddress 实体创建一个字段集,然后将其添加到 OrderForm。

use Zend\Form\Fieldset;

class BusinessAddressFieldset extends Fieldset
{
  public function __construct($entityManager)
{

    parent::__construct('businessAddress');

    $this->add(array(
        'name' => 'firstName',
        'type' => 'Zend\Form\Element\Text',
        'options' => array(
            'label' => 'First Name',
        ),
        'attributes' => array(
            'type' => 'text',
        ),
    ));

    $this->add(array(
        'name' => 'lastName',
        'type' => 'Zend\Form\Element\Text',
        'options' => array(
            'label' => 'Last Name',
        ),
        'attributes' => array(
            'type' => 'text',
        ),
    ));
}

}

然后将字段集添加到您的 OrderForm 中:

class OrderForm
extends \Zend\Form\Form
{
    public function __construct()
    {
        parent::__construct('order');

        // add fields

        $this->add(new BusinessAddressFieldset()); 

    }
}

确保您设置的字段集的名称与引用的名称相匹配,并且您设置了表单 hydrator。