Using the @ComposedObject Zend Framework 2 Form Annotation
22 August 2012
WARNING: This post was written a long time ago. It exists here as a record
and may not reflect my current views or opinions. Also, any code,
technologies or examples may be out of date.
Recently I started playing with Zend Framework 2 Form Annotations. These
certainly make building forms much simpler. If you have not heard about this
yet see Matthew Weier O’Phinney’s
post and the ZF2
Documentation</a>.
After getting it up and running, I found out about about the @ComposedObject
annotation. It seemed very useful, however, it took a bit of fiddling to get
it up and running. Here’s how I did it.
The @ComposedObject annotation lets you create a fieldset inside a form
which was created from one annotated class, by using the form annotations from
another class.
To set this up I created 2 classes User and Address:
The Address class is pretty straight forward, however, if you look at the
annotations for the User class, you will see that the address property is annotated as being a
ComposedObject of type Album\Model\Address.
In the controller you can now add the code to create the form:
And a view script to display it:
Note that a whole fieldset can be displayed with the formCollection() view
helper.
At this point, when you view this action in the browser the form fields should
all be present. However, all the fields will be empty rather than containing the
data from the object. The reason for this is the User and Address classes
have been annotated to use the ArraySerializable hydrator which requires
getArrayCopy and exchangeArray methods to be defined.
The reason for choosing ArraySerializable instead of another hydrator, is
that, in order for fieldsets to be hydrated they need the extracted data from
the composed object to be presented as a sub-array. The other hydrators will
just return the object as an element in the array, but ArraySerializable lets
us define the array that is returned.
For Address these 2 methods are simple since it just contains simple fields:
However, for User we need to call the methods of Address to get back and
write a serialized sub array: