简体   繁体   中英

ZF2 + Doctrine 2: Hydrate related objects via ZF2 Form

Our application (Zend Framework 2 + Doctrine 2) has an Order entity which references its related objects like BillingAddress and so on. We have implemented a REST API to create and update orders. The data is passed to this API as an associative array and the data of the referenced objects can be encapsulated inside this array. IE the data received by the Order API looks like this

$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'
    ]
];

First thing to note about this is the fact that the given BillingAddress can either be new or an existing one! In the latter case an id would be part of the billing_address data.

Using the DoctrineObject hydrator

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

Doctrine takes care of updating or creating the referenced objects automagically. This is how we are doing it so far: Take the received data, do a little processing to sanitize and validate the data and call the hydrator.

However we now want to use Zend\\Form\\Form for easy sanitizing of the received data. Setting up a Form for the simple attributes of the Order is pretty easy

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

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

But I struggle with the referenced objects. How do I set up the form so that the referenced objects are created or updated by Doctrine just like using the hydrator directly? Do I have to create a "sub-form/fieldset"?

Yes, you can create a fieldset for the BusinessAddress entity and then add it to the 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',
        ),
    ));
}

}

And then add the field set to your OrderForm:

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

        // add fields

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

    }
}

Make sure that the name of the fieldset that you set, match the name of the reference and that you set the form hydrator.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM