diff --git a/src/ZfrRest/Hydrator/ResourceHydrator.php b/src/ZfrRest/Hydrator/ResourceHydrator.php new file mode 100644 index 0000000..0595a80 --- /dev/null +++ b/src/ZfrRest/Hydrator/ResourceHydrator.php @@ -0,0 +1,44 @@ + + * @licence MIT + */ +class ResourceHydrator implements HydratorInterface +{ + /** + * {@inheritDoc} + */ + public function extract($object) + { + // TODO: Implement extract() method. + } + + /** + * {@inheritDoc} + */ + public function hydrate(array $data, $object) + { + // TODO: Implement hydrate() method. + } +} diff --git a/src/ZfrRest/View/Renderer/DefaultResourceRenderer.php b/src/ZfrRest/View/Renderer/DefaultResourceRenderer.php new file mode 100644 index 0000000..8fab86a --- /dev/null +++ b/src/ZfrRest/View/Renderer/DefaultResourceRenderer.php @@ -0,0 +1,142 @@ + + * @licence MIT + */ +class DefaultResourceRenderer extends AbstractResourceRenderer +{ + /** + * @var ResourceMetadataFactory + */ + protected $resourceMetadataFactory; + + /** + * @var HydratorPluginManager + */ + protected $hydratorPluginManager; + + /** + * @param ResourceMetadataFactory $metadataFactory + * @param HydratorPluginManager $pluginManager + */ + public function __construct(ResourceMetadataFactory $metadataFactory, HydratorPluginManager $pluginManager) + { + $this->resourceMetadataFactory = $metadataFactory; + $this->hydratorPluginManager = $pluginManager; + } + + /** + * {@inheritDoc} + */ + public function render($nameOrModel, $values = null) + { + if (!$nameOrModel instanceof ResourceModel) { + return; + } + + $resource = $nameOrModel->getResource(); + + if ($resource->isCollection()) { + $payload = $this->renderCollection($resource); + } else { + $payload = $this->renderItem($resource); + } + + return json_encode($payload); + } + + /** + * {@inheritDoc} + */ + public function renderItem(ResourceInterface $resource) + { + $resourceMetadata = $resource->getMetadata(); + + $hydratorName = $resourceMetadata->getHydratorName(); + $hydrator = $this->hydratorPluginManager->get($hydratorName); + + // First render the data of the resource only + $data = $hydrator->extract($resource->getData()); + + // Then, handle each association + $classMetadata = $resourceMetadata->getClassMetadata(); + $associations = $classMetadata->getAssociationNames(); + + foreach ($associations as $association) { + if (!$resourceMetadata->hasAssociationMetadata($association)) { + unset($data[$association]); + continue; + } + + $associationMetadata = $resourceMetadata->getAssociationMetadata($association); + $associationResourceMetadata = $this->resourceMetadataFactory->getMetadataForClass( + $classMetadata->getAssociationTargetClass($association) + ); + + $associationHydrator = $associationResourceMetadata->getHydratorName(); + + switch($associationMetadata['extraction']) { + case 'NONE': + unset($data[$association]); + break; + + case 'ID': + $data = array_merge($data, [ + $association => $associationHydrator->extractIdentifiers($data[$association]) + ]); + + break; + + case 'EMBEDDED': + $associationResource = new Resource($data[$association], $associationResourceMetadata); + + if ($classMetadata->isCollectionValuedAssociation($association)) { + $data = array_merge($data, $this->renderCollection($associationResource); + } else { + $data = array_merge($data, $this->renderItem($associationResource)); + } + } + } + + return $hydrator->extract($resource->getData()); + } + + /** + * {@inheritDoc} + */ + public function renderCollection(ResourceInterface $resource) + { + // TODO: Implement renderCollection() method. + } +}