I am developing a RESTful ZF2 application and using the TableGateway implementation (subclass of Zend\Db\TableGateway ) in combination with a simple model mapper , similar to the ZF2 example album example .
Table class
<?php namespace Courses\Model; use ... class CourseTable { protected $tableGateway; public function __construct(TableGateway $tableGateway) { $this->tableGateway = $tableGateway; } public function findOnceByID($id) { $select = new Select(); $where = new Where(); $select->columns(array( 'id', 'title', 'details', )); $select->from($this->tableGateway->getTable()); $select->where($where, Predicate::OP_AND); $resultSet = $this->tableGateway->selectWith($select); return $resultSet; } }
Mapping class
<?php namespace Courses\Model; use ... class CourseDetails implements ArraySerializableInterface { public $id; public $title; public $details; public function exchangeArray(array $data) { $this->id = (isset($data['id'])) ? $data['id'] : null; $this->title = (isset($data['title'])) ? $data['title'] : null; $this->details = (isset($data['details'])) ? $data['details'] : null; } public function getArrayCopy() { return get_object_vars($this); } }
controller
<?php namespace Courses\Controller; use ... class CoursesController extends RestfulController // extends AbstractRestfulController { protected $acceptCriteria = array( 'Zend\View\Model\JsonModel' => array( 'application/json', ), 'Zend\View\Model\FeedModel' => array( 'application/rss+xml', ), ); private $courseTable; public function get($id) { $course = $this->getCourseTable()->findOnceByID($id)->current(); $viewModel = $this->acceptableViewModelSelector($this->acceptCriteria); $viewModel->setVariables(array('data' => array( 'id' => $courseDetails->id, 'title' => $courseDetails->title, 'details' => $courseDetails->details ))); return $viewModel; } ... }
It works for shallow output as follows:
{ "data":{ "id":"123", "title":"test title", "details":"test details" } }
But now I need multidimensional output with nested lists:
{ "data":{ "id":"123", "title":"test title", "details":"test details", "events":{ "count":"3", "events_list":[ <- main list { "id":"987", "date":"2013-07-20", "place":"Berlin", "trainers":{ "count":"1", "trainers_teamid":"14", "trainers_teamname":"Trainers Team Foo", "trainers_list":[ <- nested list { "id":"135", "name":"Tom" } ] } }, { "id":"876", "date":"2013-07-21", "place":"New York", "trainers":{ "count":"3", "trainers_teamid":"25", "trainers_teamname":"Trainers Team Bar", "trainers_list":[ <- nested list { "id":"357", "name":"Susan" }, { "id":"468", "name":"Brian" }, { "id":"579", "name":"Barbara" } ] } }, { "id":"756", "date":"2013-07-29", "place":"Madrid", "trainers":{ "count":"1", "trainers_teamid":"36", "trainers_teamname":"Trainers Team Baz", "trainers_list":[ <- nested list { "id":"135", "name":"Sandra" } ] ] } ] } } }
How / where should I collect data in this structure? Directly in the converter so that it contains all the data? Or should I handle this with a few anb database queries in order to create a structure in the controller?