August 24, 2007

HowTo: Converting data to JSON (0.8.3 teaser)

Filed under: ZenMagick — DerManoMann @ 11:05 am

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:


$flatObj = $this->flattenObject($zm_countries->getCountries(), array('id', 'name'));
$json = $this->toJSON($flatObj);
$this->setJSONHeader($json);
In words, the three steps are:

  1. Load all countries and use the method flattenObject(..) to reduce the countries array (array of ZMCountry instances) 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')
  2. The call of the toJSON(..) method is a wrapper around the included PHP JSON library that converts the nested arrays to a JSON string.
  3. 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:

  1. ZMProduct has a getAttributes() method. That, in turn, returns a list of ZMAttribute instances.
  2. ZMAttribute, again, has a method getValues() that creates a list of ZMAttributeValue objects
  3. ZMAttributeValue is 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!

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

You must be logged in to post a comment.