HowTo: Converting data to JSON (0.8.3 teaser)
Today was a good day for Ajax support in ZenMagick. I made a small but significant change to ZMAjaxController::flattenObject($object, $methods=null, $formatter=null).
(If you are not into funny PHP programming you might want to stop reading now…)
To understand what I am talking about, let’s look at an example first. This is the code to retrieve and return a list of all countries as JSON:
In words, the three steps are:
$flatObj = $this->flattenObject($zm_countries->getCountries(), array('id', 'name'));
$json = $this->toJSON($flatObj);
$this->setJSONHeader($json);
- Load all countries and use the method
flattenObject(..)to reduce the countries array (array ofZMCountryinstances) to a set of nested arrays where the inner arrays are maps that contain country id and country name;
for example:array ('id'=> 3, 'name' => 'Germany') - The call of the
toJSON(..)method is a wrapper around the included PHP JSON library that converts the nested arrays to a JSON string. - The third line creates the actual response (incl. a X-JSON header).
So, the country instances are converted to a map, based on the given method list. It’s worth mentioning here that wherever methods and method names are involved in ZenMagick, the used conventions are very similar to those for Java Beans, in particular with regards to introspection, naming and the whole things around get/set methods to access class properties.
The latest change to the flattedObject method now allows to use nested arrays to control this behavior recursively.
The easiest way to illustrate is another example. This is an example taken from the new Ajax product controller that can be used to load product information.
Now, here we have the issue that there are multiple layers of objects involved:
ZMProducthas agetAttributes()method. That, in turn, returns a list ofZMAttributeinstances.ZMAttribute, again, has a methodgetValues()that creates a list ofZMAttributeValueobjectsZMAttributeValueis the last object in the chain
So, what we can do here is tell the method that ‘id’, ‘name’, ‘description’ and ‘model’ are immediate properties of the product object. ‘attributes’, in contrast, contains other objects and we are only interested in ‘id’, ‘type’, ‘name’ and ‘values’, another list of objects. And so on and on…
$productId = $zm_request->getParameter('productId', 0);
$flatObj = $this->flattenObject($zm_products->getProductForId($productId),
array(’id’, ‘name’, ‘description’, ‘model’,
‘attributes’ => array(’id’, ‘type’, ‘name’,
‘values’ => array(’id’, ‘name’, ‘default’)
)));
Effectively, this allows, starting from a given object hierarchy, to create a JSON representation that contains exactly the properties we are interested in! And without telling too much, the new ajax demo is really so much better!
