2017-07-19 2 views
0

Est-il possible d'imbriquer des hydrateurs d'agrégats? Si j'ai les classes suivantes:zf2 - Hydrateurs agrégés imbriqués

class Appointment{ 
    public date; 
    public startTime; 
    public endTime; 
    public User; //* @var User */ 
} 

class User{ 
    public Location; //* @var Location*/ 
} 

... étant renseigné avec le AggregateHydrator suivant (créé à partir d'une usine):

class AppointmentModelHydratorFactory implements FactoryInterface 
{ 
    public function createService(ServiceLocatorInterface $serviceLocator) { 
     $serviceManager = $serviceLocator->getServiceLocator(); 
     $arrayHydrator = new ArraySerializable(); 
     $arrayHydrator->addStrategy('date', new DateTimeStrategy()) 
      ->addStrategy('endTime', new TimeStrategy()) 
      ->addStrategy('startTime', new TimeStrategy()); 

     $aggregateHydrator = new AggregateHydrator(); 
     $aggregateHydrator->add($arrayHydrator); 
     $aggregateHydrator->add($serviceLocator->get('Hydrator\User')); 
     return $aggregateHydrator; 
    } 
} 

Avec la UserHydratorFactory ressemblant à:

class UserHydratorFactory implements FactoryInterface 
{ 
    public function createService(ServiceLocatorInterface $serviceLocator) { 
     $sm = $serviceLocator->getServiceLocator(); 
     $userHydrator = new UserHydrator($sm->get('User\Mapper')); 
     $aggregateHydrator = new AggregateHydrator(); 
     $aggregateHydrator->add($userHydrator); 
     $aggregateHydrator->add($sm->get('HydratorManager')->get('Hydrator\User\Location')); 
     return $aggregateHydrator; 
} 

}

Ceci lance une expection car le modèle est retourné comme nul, mais je Si je commente l'ajout de l'hydrateur de localisation à l'hydrateur de l'utilisateur, cela fonctionne bien (bien que les données de localisation ne soient pas chargées). Donc je me demandais si les hydrators agrégés peuvent être imbriqués?

Répondre

0

Il n'est pas intégré, mais faisable.

namespace Hydrator; 
use Zend\Stdlib\Hydrator\HydratorInterface; 
class NestedHydrator implements HydratorInterface 
{ 
    protected $inner_hydrator; 
    private $empty; 


    public function __construct ($inner_hydrator, $empty) 
    { 
     $this->inner_hydrator = $inner_hydrator; 
     $this->empty = $empty; 
    } 


    public function extract ($object) 
    { 
     return [ 
      $this->getPath() => $this->inner_hydrator->extract ($object->{$this->getPath()}) 
     ]; 
    } 


    public function hydrate (array $data, $object) 
    { 
     $object->{$this->getPath()} = $this->inner_hydrator->hydrate ($data [$this->getPath()], $this->empty); 

     return $object; 
    } 


    protected function getPath() 
    { 
     return get_class ($this->empty); 
    } 
} 

Et puis:

$u = new User(); 
$u->Location = "4 Clinton Rd."; 

$a = new Appointment(); 
$a->date = "yesterday"; 
$a->startTime = "7:00"; 
$a->endTime = "8:00"; 
$a->User = $u; 

$h = new AggregateHydrator(); 
$h->add (new ObjectProperty()); 
$nested = new \Hydrator\NestedHydrator(new ObjectProperty(), new User()); 
$h->add ($nested); 
$data = $h->extract ($a); 

$b = $h->hydrate ($data, new Appointment()); 
$this->assertEquals ($a, $b);