Hydrators are used when you need to get data in or out of an object / object, which can be when using a form, as well as when saving or loading an object from storage.
I would not use Hydrator to populate your objects with related objects (for example, to add an antist object to your album). I would leave it up to your services / cartographers.
Here is an example of how I will do this:
Album.php
<?php class Album { // .. properties / getters/setters etc .. public function setArtist(ArtistInterface $artist) { $this->artist = $artist; } public function getArtist() { return $this->artist; } }
AlbumHydrator.php
this may change, you will use getters / setters or properties, look at the base hydrators to decide which route you want to take.
Your hydrator will take the collected objects and return the data that you need either to display the form, or to maintain persistence, etc.
<?php class AlbumHydrator // extends Zend\Stdlib\Hydrator\ClassMethods { public function extract($object) { return array( 'artist_id' => $object->getArtist()->getId(), 'albumn_name' => $object->getAlbumName() ) }
AlbumService.php
<?php use Zend\ServiceManager\ServiceManagerAwareInterface; use Zend\ServiceManager\ServiceManager; class AlbumService implements ServiceManagerAwareInterface { public function find($id) { $album = $this->_getAlbumMapper()->find($id); $artist = $this->_getArtistMapper()->findByAlbum($id); $album->setArtist($artist); return $album; } protected function _getAlbumMapper() { return $this->getServiceManager() ->get('AlbumMapper') ; }
You must configure your service in the Service Manager configuration as follows:
'AlbumService' => function($sm) { $mapper = $sm->get('AlbumMapper'); $service = new Application\Service\AlbumService(); $service->setAlbumMapper($mapper); return $service; },
Then you use your service to create a graph of the object you need. You will have separate cartographers for each of the entities, and services can use mappers to generate the required objects.
You usually have a Hydrator for each of the entities, and cartographers will use them to populate objects for you. It will depend on your implementation, you can use TableGateway or something instead of cartographers, which will work fine anyway.
An example is now accessing your objects when inside your controller
SomeController.php
public function albumAction() { $id = (int) $this->params()->fromRoute('id', FALSE); if( ! $id) { // do something with errors etc .. return $this->redirect()->toRoute('default_route', array( 'controller' => 'index', 'action' => 'index' )); } $request = $this->getRequest(); $album = $this->getServiceLocator()->get('AlbumService')->find($id); $artistName = $album->getArtist()->getName(); return new ViewMdoel( 'album' => $ablum, 'artistName' => $artistName ); }
Custom object graphs when using collections are a bit more complicated, but I would try to use lazy loading and virtual proxies for such an installation, which basically delays the loading of objects you need until you require them, check:
http://phpmaster.com/intro-to-virtual-proxies-1/ http://phpmaster.com/intro-to-virtual-proxies-2/