/** * {@inheritdoc} */ public function getIriFromItem($item, $referenceType = RouterInterface::ABSOLUTE_PATH) { if ($resource = $this->resourceCollection->getResourceForEntity($item)) { return $this->router->generate($this->getRouteName($resource, 'item'), ['id' => $this->propertyAccessor->getValue($item, 'id')], $referenceType); } throw new \InvalidArgumentException(sprintf('No resource associated with the type "%s".', get_class($item))); }
public function getAttributeMetadataFor(ClassMetadataInterface $classMetadata, $attributeName, array $normalizationGroups = null, array $denormalizationGroups = null) { if ($classMetadata->hasAttributeMetadata($attributeName)) { return $classMetadata->getAttributeMetadata($attributeName); } $attributeMetadata = new AttributeMetadata(); $reflectionProperty = $this->getReflectionProperty($classMetadata->getReflectionClass(), $attributeName); if (!$reflectionProperty) { return $attributeMetadata; } $types = $this->propertyInfo->getTypes($reflectionProperty); if (!isset($types[0])) { return $attributeMetadata; } $type = $types[0]; $attributeMetadata = $attributeMetadata->withType($type); $class = $type->getClass(); $link = $this->resourceCollection->getResourceForEntity($class) || $type->isCollection() && $type->getCollectionType() && ($class = $type->getCollectionType()->getClass()) && $this->resourceCollection->getResourceForEntity($class); $attributeMetadata = $attributeMetadata->withLink($link)->withLinkClass($class); if (!$link) { return $attributeMetadata; } if (null === $normalizationGroups) { $attributeMetadata = $attributeMetadata->withNormalizationLink(true); } if (null === $denormalizationGroups) { $attributeMetadata = $attributeMetadata->withDenormalizationLink(true); } return $attributeMetadata; }
/** * Does the conversion. * * @param GetResponseEvent $event */ public function onKernelRequest(GetResponseEvent $event) { $request = $event->getRequest(); if (!$request->attributes->has('_resource')) { return; } $shortName = $request->attributes->get('_resource'); $resourceType = $this->resourceTypeCollection->getResourceForShortName($shortName); if (!$resourceType) { throw new InvalidArgumentException(sprintf('The resource "%s" cannot be found.', $shortName)); } $request->attributes->set('_resource_type', $resourceType); }
/** * @param AttributeMetadataInterface $attributeMetadata * * @return mixed */ public function guess(AttributeMetadataInterface $attributeMetadata) { $value = null; $type = null; if (true === ($isDoctrine = isset($attributeMetadata->getTypes()[0]))) { $type = $attributeMetadata->getTypes()[0]; } // Guess associations if ($isDoctrine && 'object' === $type->getType() && 'DateTime' !== $type->getClass()) { $class = $type->isCollection() ? $type->getCollectionType()->getClass() : $type->getClass(); $resource = $this->resourceCollection->getResourceForEntity($class); $classMetadata = $this->classMetadataFactory->getMetadataFor($resource->getEntityClass(), $resource->getNormalizationGroups(), $resource->getDenormalizationGroups(), $resource->getValidationGroups()); $id = $this->guess($classMetadata->getIdentifier()); $value = $this->iriConverter->getIriFromResource($resource) . '/' . $id; if ($type->isCollection()) { $value = [$value]; } } // Guess by faker if (null === $value) { try { $value = call_user_func([$this->generator, $attributeMetadata->getName()]); } catch (\InvalidArgumentException $e) { } } // Guess by field name if (null === $value) { $value = $this->guessFormat(Inflector::tableize($attributeMetadata->getName())); } // Guess by Doctrine type if (null === $value && $isDoctrine) { switch ($type->getType()) { case 'string': $value = $this->generator->sentence; break; case 'int': $value = $this->generator->numberBetween; break; case 'bool': $value = $this->generator->boolean; break; case 'object': if ('DateTime' !== $type->getClass()) { throw new \InvalidArgumentException(sprintf('Unknown Doctrine object type %s in field %s', $type->getClass(), $attributeMetadata->getName())); } $value = $this->generator->dateTime; break; } } return $this->clean($value); }
/** * Gets the range of the property. * * @param AttributeMetadataInterface $attributeMetadata * * @return string|null */ private function getRange(AttributeMetadataInterface $attributeMetadata) { if (isset($attributeMetadata->getTypes()[0])) { $type = $attributeMetadata->getTypes()[0]; if ($type->isCollection() && ($collectionType = $type->getCollectionType())) { $type = $collectionType; } switch ($type->getType()) { case 'string': return 'xmls:string'; case 'int': return 'xmls:integer'; case 'float': return 'xmls:double'; case 'bool': return 'xmls:boolean'; case 'object': $class = $type->getClass(); if ($class) { if ('DateTime' === $class) { return 'xmls:dateTime'; } if ($resource = $this->resourceCollection->getResourceForEntity($type->getClass())) { return sprintf('#%s', $resource->getShortName()); } } break; } } }
/** * Generates a context according to the type requested. * * @param Request $request * @param $shortName * * @return array */ public function __invoke(Request $request, $shortName) { $request->attributes->set('_api_format', 'jsonld'); if ('Entrypoint' === $shortName) { return ['@context' => $this->contextBuilder->getEntrypointContext()]; } if (isset(self::$reservedShortNames[$shortName])) { $resource = null; } else { $resource = $this->resourceTypeCollection->getResourceForShortName($shortName); if (!$resource) { throw new NotFoundHttpException(); } } return ['@context' => $this->contextBuilder->getContext($resource)]; }
/** * Gets or creates the {@see AttributeMetadata} of the given name. * * @param ClassMetadata $classMetadata * @param string $attributeName * @param string[]|null $normalizationGroups * * @return AttributeMetadata */ private function getOrCreateAttribute(ClassMetadata $classMetadata, $attributeName, array $normalizationGroups = null, array $denormalizationGroups = null) { if (isset($classMetadata->getAttributes()[$attributeName])) { return $classMetadata->getAttributes()[$attributeName]; } $attributeMetadata = new AttributeMetadata($attributeName); $classMetadata->addAttribute($attributeMetadata); $reflectionProperty = $this->getReflectionProperty($classMetadata->getReflectionClass(), $attributeName); if (!$reflectionProperty) { return $attributeMetadata; } $types = $this->propertyInfo->getTypes($reflectionProperty); if (null !== $types) { $attributeMetadata->setTypes($types); } if (!isset($types[0])) { return $attributeMetadata; } $class = $types[0]->getClass(); if (!$this->resourceCollection->getResourceForEntity($class) && !($types[0]->isCollection() && $types[0]->getCollectionType() && ($class = $types[0]->getCollectionType()->getClass()) && $this->resourceCollection->getResourceForEntity($class))) { return $attributeMetadata; } if (null === $normalizationGroups) { $attributeMetadata->setNormalizationLink(true); } if (null === $denormalizationGroups) { $attributeMetadata->setDenormalizationLink(true); } if ($attributeMetadata->isNormalizationLink() && $attributeMetadata->isDenormalizationLink()) { return $attributeMetadata; } if (!$this->serializerClassMetadataFactory || !($relationSerializerMetadata = $this->serializerClassMetadataFactory->getMetadataFor($class))) { $attributeMetadata->setNormalizationLink(true); $attributeMetadata->setDenormalizationLink(true); return $attributeMetadata; } foreach ($relationSerializerMetadata->getAttributesMetadata() as $serializerAttributeMetadata) { $serializerAttributeGroups = $serializerAttributeMetadata->getGroups(); if (null !== $normalizationGroups && 1 <= count(array_intersect($normalizationGroups, $serializerAttributeGroups))) { $normalizationLink = false; } if (null !== $denormalizationGroups && 1 <= count(array_intersect($denormalizationGroups, $serializerAttributeGroups))) { $denormalizationLink = false; } if (isset($normalizationLink) && isset($denormalizationLink)) { return $attributeMetadata; } } if (!isset($normalizationLink)) { $attributeMetadata->setNormalizationLink(true); } if (!isset($denormalizationLink)) { $attributeMetadata->setDenormalizationLink(true); } return $attributeMetadata; }
/** * read the configuration and dispatch event * * @param $version * @param $entity * @param $eventName * @param ResourceCollectionInterface $resourceResolver * @param EventDispatcherInterface $dispatcher * * @return null * @throws \Exception */ public function dispatchEvent($version, $entity, $eventName, ResourceCollectionInterface $resourceResolver, EventDispatcherInterface $dispatcher) { /** @var \Eliberty\ApiBundle\Api\Resource $resource */ $resource = $resourceResolver->getResourceForEntityWithVersion(get_class($entity), $version); if (null === $resource) { $entityClass = get_class($entity); $shortName = substr($entityClass, strrpos($entityClass, '\\') + 1); $resource = $resourceResolver->getResourceForShortNameWithVersion($shortName, $version); } if (null === $resource) { return null; } if ($resource->hasEventListener($eventName)) { $events = $resource->getListener($eventName); foreach ($events as $eventData) { $event = $this->createEventClass($entity, $eventData); $eventName = isset($eventData['eventName']) ? $eventData['eventName'] : $eventName; $dispatcher->dispatch($eventName, $event); } } }
/** * Denormalizes a relation. * * @param ResourceInterface $currentResource * @param string $attributeName * @param AttributeMetadataInterface $attributeMetadata * @param string $class * @param mixed $value * @param array $context * * @return object|null * * @throws InvalidArgumentException */ private function denormalizeRelation(ResourceInterface $currentResource, $attributeName, AttributeMetadataInterface $attributeMetadata, $class, $value, array $context) { if ('DateTime' === $class) { return $this->serializer->denormalize($value, $class ?: null, self::FORMAT, $context); } // Always allow IRI to be compliant with the Hydra spec if (is_string($value)) { try { return $this->iriConverter->getItemFromIri($value); } catch (InvalidArgumentException $e) { throw new InvalidArgumentException(sprintf('IRI not supported (found "%s" in "%s" of "%s")', $value, $attributeName, $currentResource->getEntityClass()), $e->getCode(), $e); } } if (!($resource = $this->resourceCollection->getResourceForEntity($class))) { throw new InvalidArgumentException(sprintf('Type not supported (found "%s" in attribute "%s" of "%s")', $class, $attributeName, $currentResource->getEntityClass())); } if (!$attributeMetadata->isDenormalizationLink()) { return $this->serializer->denormalize($value, $class, self::FORMAT, $this->createRelationContext($resource, $context)); } throw new InvalidArgumentException(sprintf('Nested objects for attribute "%s" of "%s" are not enabled. Use serialization groups to change that behavior.', $attributeName, $currentResource->getEntityClass())); }
/** * {@inheritdoc} */ public function parse(array $item) { list($io, $entityClass) = explode(':', $item['class'], 2); $resource = $this->resourceCollection->getResourceForEntity($entityClass); return $this->parseClass($resource, $entityClass, $io); }
/** * Bootstrap relation context. * * @param ResourceInterface $resource * @param string $class * * @return array */ public function bootstrapRelation(ResourceInterface $resource, $class) { return ['resource' => $this->resourceCollection->getResourceForEntity($class), 'json_ld_has_context' => true, 'json_ld_normalization_groups' => $resource->getNormalizationGroups(), 'json_ld_denormalization_groups' => $resource->getDenormalizationGroups(), 'json_ld_validation_groups' => $resource->getValidationGroups()]; }
/** * Returns the resource associated with the given type or null. * * @param Type $type * * @return ResourceInterface|null */ public function getResourceFromType(Type $type) { if ('object' === $type->getType() && ($class = $type->getClass()) && ($resource = $this->resourceCollection->getResourceForEntity($class))) { return $resource; } }