public function testLinkCollectionMayBeInjected() { $entity = new stdClass; $hal = new Entity($entity, 'id', 'route', array('foo' => 'bar')); $links = new LinkCollection(); $hal->setLinks($links); $this->assertSame($links, $hal->getLinks()); }
public function testInjectEntitySelfLinkWithIdentifierShouldAddSelfLinkWithIdentifierRouteParam() { $routeIdentifier = 'id'; $linkCollection = new LinkCollection(); $resource = new Entity([], 123); $resource->setLinks($linkCollection); $injector = new SelfLinkInjector(); $injector->injectSelfLink($resource, 'foo', $routeIdentifier); $this->assertTrue($linkCollection->has('self')); $selfLink = $linkCollection->get('self'); $linkRouteParams = $selfLink->getRouteParams(); $this->assertArrayHasKey($routeIdentifier, $linkRouteParams); }
/** * Return a HAL entity with just a self link */ public function extract($value) { if (is_null($value)) { return $value; } $entityValues = $this->getHydratorForEntity($value)->extract($value); $entityMetadata = $this->getMetadataMap()[ClassUtils::getRealClass(get_class($value))]; $link = new Link('self'); $link->setRoute($entityMetadata['route_name']); $link->setRouteParams(array($entityMetadata['route_identifier_name'] => $entityValues[$entityMetadata['entity_identifier_name']])); $linkCollection = new LinkCollection(); $linkCollection->add($link); $halEntity = new HalEntity(new stdClass()); $halEntity->setLinks($linkCollection); return $halEntity; }
public function extract($value) { if (!method_exists($value, 'getTypeClass')) { return; } $config = $this->getMetadataMap()[$value->getTypeClass()->name]; $filter = new FilterChain(); $filter->attachByName('WordCamelCaseToUnderscore')->attachByName('StringToLower'); // Better way to create mapping name? // FIXME: use zf-hal collection_name $link = new Link('self'); $link->setRoute($config['route_name']); $link->setRouteParams(array('id' => null)); $filterValue = array('field' => $value->getMapping()['mappedBy'] ?: $value->getMapping()['inversedBy'], 'type' => isset($value->getMapping()['joinTable']) ? 'ismemberof' : 'eq', 'value' => $value->getOwner()->getId()); $link->setRouteOptions(array('query' => array($this->getFilterKey() => array($filterValue)))); $linkCollection = new LinkCollection(); $linkCollection->add($link); $halEntity = new HalEntity(new stdClass()); $halEntity->setLinks($linkCollection); return $halEntity; }
/** * Render an individual entity * * Creates a hash representation of the Entity. The entity is first * converted to an array, and its associated links are injected as the * "_links" member. If any members of the entity are themselves * Entity objects, they are extracted into an "_embedded" hash. * * @param Entity $halEntity * @param bool $renderEntity * @param int $depth depth of the current rendering recursion * @param int $maxDepth maximum rendering depth for the current metadata * @throws Exception\CircularReferenceException * @return array */ public function renderEntity(Entity $halEntity, $renderEntity = true, $depth = 0, $maxDepth = null) { $this->getEventManager()->trigger(__FUNCTION__, $this, ['entity' => $halEntity]); $entity = $halEntity->entity; $entityLinks = clone $halEntity->getLinks(); // Clone to prevent link duplication $metadataMap = $this->getMetadataMap(); if (is_object($entity)) { if ($maxDepth === null && $metadataMap->has($entity)) { $maxDepth = $metadataMap->get($entity)->getMaxDepth(); } if ($maxDepth === null) { $entityHash = spl_object_hash($entity); if (isset($this->entityHashStack[$entityHash])) { // we need to clear the stack, as the exception may be caught and the plugin may be invoked again $this->entityHashStack = []; throw new Exception\CircularReferenceException(sprintf("Circular reference detected in '%s'. %s", get_class($entity), "Either set a 'max_depth' metadata attribute or remove the reference")); } $this->entityHashStack[$entityHash] = get_class($entity); } } if (!$renderEntity || $maxDepth !== null && $depth > $maxDepth) { $entity = []; } if (!is_array($entity)) { $entity = $this->getEntityExtractor()->extract($entity); } foreach ($entity as $key => $value) { if (is_object($value) && $metadataMap->has($value)) { $value = $this->getResourceFactory()->createEntityFromMetadata($value, $metadataMap->get($value), $this->getRenderEmbeddedEntities()); } if ($value instanceof Entity) { $this->extractEmbeddedEntity($entity, $key, $value, $depth + 1, $maxDepth); } if ($value instanceof Collection) { $this->extractEmbeddedCollection($entity, $key, $value, $depth + 1, $maxDepth); } if ($value instanceof Link) { // We have a link; add it to the entity if it's not already present. $entityLinks = $this->injectPropertyAsLink($value, $entityLinks); unset($entity[$key]); } if ($value instanceof LinkCollection) { foreach ($value as $link) { $entityLinks = $this->injectPropertyAsLink($link, $entityLinks); } unset($entity[$key]); } } $halEntity->setLinks($entityLinks); $entity['_links'] = $this->fromResource($halEntity); $payload = new ArrayObject($entity); $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, ['payload' => $payload, 'entity' => $halEntity]); if (isset($entityHash)) { unset($this->entityHashStack[$entityHash]); } return $payload->getArrayCopy(); }
protected function normalizeEntityInputFilterName(Model\InputFilterEntity $entity, $links, HalJsonModel $model) { $entity['input_filter_name'] = str_replace('\\', '-', $entity['input_filter_name']); $halEntity = new Entity($entity, $entity['input_filter_name']); if ($links->has('self')) { $links->remove('self'); } $halEntity->setLinks($links); $model->setPayload($halEntity); }
/** * Create an Entity instance and inject it with a self relational link if necessary * * @param Entity|array|object $entity * @param string $route * @param string $routeIdentifierName * @return Entity */ public function createEntity($entity, $route, $routeIdentifierName) { $metadataMap = $this->getMetadataMap(); switch (true) { case is_object($entity) && $metadataMap->has($entity): $generatedEntity = $this->createEntityFromMetadata($entity, $metadataMap->get($entity)); $halEntity = new Entity($entity, $generatedEntity->id); $halEntity->setLinks($generatedEntity->getLinks()); break; case !$entity instanceof Entity: $id = $this->getIdFromEntity($entity) ?: null; $halEntity = new Entity($entity, $id); break; case $entity instanceof Entity: default: $halEntity = $entity; // as is break; } $metadata = !is_array($entity) && $metadataMap->has($entity) ? $metadataMap->get($entity) : false; if (!$metadata || $metadata && $metadata->getForceSelfLink()) { $this->injectSelfLink($halEntity, $route, $routeIdentifierName); } return $halEntity; }
/** * Create an Entity instance and inject it with a self relational link * * @param Entity|array|object $entity * @param string $route * @param string $routeIdentifierName * @return Entity */ public function createEntity($entity, $route, $routeIdentifierName) { $metadataMap = $this->getMetadataMap(); switch (true) { case is_object($entity) && $metadataMap->has($entity): $generatedEntity = $this->createEntityFromMetadata($entity, $metadataMap->get($entity)); $halEntity = new Entity($entity, $generatedEntity->id); $halEntity->setLinks($generatedEntity->getLinks()); break; case !$entity instanceof Entity: $id = $this->getIdFromEntity($entity) ?: null; $halEntity = new Entity($entity, $id); break; case $entity instanceof Entity: default: $halEntity = $entity; // nothing special to do break; } $this->injectSelfLink($halEntity, $route, $routeIdentifierName); return $halEntity; }