/**
  * Builds default context.
  *
  * @param ContextBuilderEvent $event
  */
 public function onContextBuilder(ContextBuilderEvent $event)
 {
     $resource = $event->getResource();
     if (null === $resource) {
         return;
     }
     $context = $event->getContext();
     $prefixedShortName = sprintf('#%s', $resource->getShortName());
     $attributes = $this->classMetadataFactory->getMetadataFor($resource->getEntityClass(), $resource->getNormalizationGroups(), $resource->getDenormalizationGroups(), $resource->getValidationGroups())->getAttributes();
     foreach ($attributes as $attributeName => $attribute) {
         if ($attribute->isIdentifier()) {
             continue;
         }
         $convertedName = $this->nameConverter ? $this->nameConverter->normalize($attributeName) : $attributeName;
         if (!($id = $attribute->getIri())) {
             $id = sprintf('%s/%s', $prefixedShortName, $convertedName);
         }
         if ($attribute->isNormalizationLink()) {
             $context[$convertedName] = ['@id' => $id, '@type' => '@id'];
         } else {
             $context[$convertedName] = $id;
         }
     }
     $event->setContext($context);
 }
 /**
  * {@inheritdoc}
  */
 public function getApiDocumentation()
 {
     $classes = [];
     $entrypointProperties = [];
     foreach ($this->resourceCollection as $resource) {
         $classMetadata = $this->classMetadataFactory->getMetadataFor($resource->getEntityClass(), $resource->getNormalizationGroups(), $resource->getDenormalizationGroups(), $resource->getValidationGroups());
         $shortName = $resource->getShortName();
         $prefixedShortName = ($iri = $classMetadata->getIri()) ? $iri : '#' . $shortName;
         $collectionOperations = [];
         foreach ($resource->getCollectionOperations() as $collectionOperation) {
             $collectionOperations[] = $this->getHydraOperation($resource, $collectionOperation, $prefixedShortName, true);
         }
         $entrypointProperties[] = ['@type' => 'hydra:SupportedProperty', 'hydra:property' => ['@id' => sprintf('#Entrypoint/%s', lcfirst($shortName)), '@type' => 'hydra:Link', 'domain' => '#Entrypoint', 'rdfs:label' => sprintf('The collection of %s resources', $shortName), 'range' => 'hydra:PagedCollection', 'hydra:supportedOperation' => $collectionOperations], 'hydra:title' => sprintf('The collection of %s resources', $shortName), 'hydra:readable' => true, 'hydra:writable' => false];
         $class = ['@id' => $prefixedShortName, '@type' => 'hydra:Class', 'rdfs:label' => $resource->getShortName(), 'hydra:title' => $resource->getShortName(), 'hydra:description' => $classMetadata->getDescription()];
         if ($description = $classMetadata->getDescription()) {
             $class['hydra:description'] = $description;
         }
         $properties = [];
         foreach ($classMetadata->getAttributes() as $attributeName => $attributeMetadata) {
             if ($attributeMetadata->isIdentifier() && !$attributeMetadata->isWritable()) {
                 continue;
             }
             if ($attributeMetadata->isNormalizationLink()) {
                 $type = 'Hydra:Link';
             } else {
                 $type = 'rdf:Property';
             }
             $property = ['@type' => 'hydra:SupportedProperty', 'hydra:property' => ['@id' => ($iri = $attributeMetadata->getIri()) ? $iri : sprintf('#%s/%s', $shortName, $attributeName), '@type' => $type, 'rdfs:label' => $attributeName, 'domain' => $prefixedShortName], 'hydra:title' => $attributeName, 'hydra:required' => $attributeMetadata->isRequired(), 'hydra:readable' => $attributeMetadata->isIdentifier() ? false : $attributeMetadata->isReadable(), 'hydra:writable' => $attributeMetadata->isWritable()];
             if ($range = $this->getRange($attributeMetadata)) {
                 $property['hydra:property']['range'] = $range;
             }
             if ($description = $attributeMetadata->getDescription()) {
                 $property['hydra:description'] = $description;
             }
             $properties[] = $property;
         }
         $class['hydra:supportedProperty'] = $properties;
         $operations = [];
         foreach ($resource->getItemOperations() as $itemOperation) {
             $operations[] = $this->getHydraOperation($resource, $itemOperation, $prefixedShortName, false);
         }
         $class['hydra:supportedOperation'] = $operations;
         $classes[] = $class;
     }
     // Entrypoint
     $classes[] = ['@id' => '#Entrypoint', '@type' => 'hydra:Class', 'hydra:title' => 'The API entrypoint', 'hydra:supportedProperty' => $entrypointProperties, 'hydra:supportedOperation' => ['@type' => 'hydra:Operation', 'hydra:method' => 'GET', 'rdfs:label' => 'The API entrypoint.', 'returns' => '#EntryPoint']];
     // Constraint violation
     $classes[] = ['@id' => '#ConstraintViolation', '@type' => 'hydra:Class', 'hydra:title' => 'A constraint violation', 'hydra:supportedProperty' => [['@type' => 'hydra:SupportedProperty', 'hydra:property' => ['@id' => '#ConstraintViolation/propertyPath', '@type' => 'rdf:Property', 'rdfs:label' => 'propertyPath', 'domain' => '#ConstraintViolation', 'range' => 'xmls:string'], 'hydra:title' => 'propertyPath', 'hydra:description' => 'The property path of the violation', 'hydra:readable' => true, 'hydra:writable' => false], ['@type' => 'hydra:SupportedProperty', 'hydra:property' => ['@id' => '#ConstraintViolation/message', '@type' => 'rdf:Property', 'rdfs:label' => 'message', 'domain' => '#ConstraintViolation', 'range' => 'xmls:string'], 'hydra:title' => 'message', 'hydra:description' => 'The message associated with the violation', 'hydra:readable' => true, 'hydra:writable' => false]]];
     // Constraint violation list
     $classes[] = ['@id' => '#ConstraintViolationList', '@type' => 'hydra:Class', 'subClassOf' => 'hydra:Error', 'hydra:title' => 'A constraint violation list', 'hydra:supportedProperty' => [['@type' => 'hydra:SupportedProperty', 'hydra:property' => ['@id' => '#ConstraintViolationList/violation', '@type' => 'rdf:Property', 'rdfs:label' => 'violation', 'domain' => '#ConstraintViolationList', 'range' => '#ConstraintViolation'], 'hydra:title' => 'violation', 'hydra:description' => 'The violations', 'hydra:readable' => true, 'hydra:writable' => false]]];
     return ['@context' => $this->getContext(), '@id' => $this->router->generate('api_hydra_vocab'), 'hydra:title' => $this->title, 'hydra:description' => $this->description, 'hydra:entrypoint' => $this->router->generate('api_json_ld_entrypoint'), 'hydra:supportedClass' => $classes];
 }
 /**
  * @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);
 }
Exemplo n.º 4
0
 /**
  * Builds the JSON-LD context for the given resource.
  *
  * @param ResourceInterface|null $resource
  *
  * @return array
  */
 public function getContext(ResourceInterface $resource = null)
 {
     $context = $this->getBaseContext();
     if ($resource) {
         $prefixedShortName = sprintf('#%s', $resource->getShortName());
         $attributes = $this->classMetadataFactory->getMetadataFor($resource->getEntityClass(), $resource->getNormalizationGroups(), $resource->getDenormalizationGroups(), $resource->getValidationGroups())->getAttributes();
         foreach ($attributes as $attributeName => $attribute) {
             if (!($id = $attribute->getIri())) {
                 $id = sprintf('%s/%s', $prefixedShortName, $attributeName);
             }
             if ($attribute->isNormalizationLink()) {
                 $context[$attributeName] = ['@id' => $id, '@type' => '@id'];
             } else {
                 $context[$attributeName] = $id;
             }
         }
     }
     return $context;
 }
 /**
  * {@inheritdoc}
  */
 public function parse(Request $request)
 {
     $resource = $request->getResource();
     $classMetadata = $this->classMetadataFactory->getMetadataFor($resource->getEntityClass(), $resource->getNormalizationGroups(), $resource->getDenormalizationGroups(), $resource->getValidationGroups());
     $request->addHeader('Content-Type', 'application/json');
     $request->setDataMode(Request::DATA_MODE_RAW);
     $rawModeData = [];
     foreach ($classMetadata->getAttributes() as $attributeMetadata) {
         if (!$classMetadata->getReflectionClass()->hasProperty($attributeMetadata->getName())) {
             // Attribute is not a property: ignore it
             continue;
         }
         $groups = $this->reader->getPropertyAnnotation($classMetadata->getReflectionClass()->getProperty($attributeMetadata->getName()), 'Symfony\\Component\\Serializer\\Annotation\\Groups');
         if ($attributeMetadata->isIdentifier() || !$attributeMetadata->isReadable() || !count(array_intersect($groups ? $groups->getGroups() : [], $resource->getDenormalizationGroups() ?: []))) {
             continue;
         }
         $rawModeData[$attributeMetadata->getName()] = $this->guesser->guess($attributeMetadata);
     }
     $request->setRawModeData($rawModeData);
 }
 /**
  * {@inheritdoc}
  */
 public function getAnnotations()
 {
     $annotations = [];
     $hydraDoc = $this->apiDocumentationBuilder->getApiDocumentation();
     $entrypointHydraDoc = $this->getResourceHydraDoc($hydraDoc, '#Entrypoint');
     /**
      * @var ResourceInterface
      */
     foreach ($this->resourceCollection as $resource) {
         $classMetadata = $this->classMetadataFactory->getMetadataFor($resource->getEntityClass());
         $prefixedShortName = ($iri = $classMetadata->getIri()) ? $iri : '#' . $resource->getShortName();
         $resourceHydraDoc = $this->getResourceHydraDoc($hydraDoc, $prefixedShortName);
         if ($hydraDoc) {
             foreach ($resource->getCollectionOperations() as $operation) {
                 $annotations[] = $this->getApiDoc(true, $resource, $operation, $resourceHydraDoc, $entrypointHydraDoc);
             }
             foreach ($resource->getItemOperations() as $operation) {
                 $annotations[] = $this->getApiDoc(false, $resource, $operation, $resourceHydraDoc);
             }
         }
     }
     return $annotations;
 }
 /**
  * Gets metadata for the given resource with the current context.
  *
  * Fallback to the resource own groups if no context is provided.
  *
  * @param ResourceInterface $resource
  * @param array             $context
  *
  * @return ClassMetadataInterface
  */
 private function getMetadata(ResourceInterface $resource, array $context)
 {
     return $this->apiClassMetadataFactory->getMetadataFor($resource->getEntityClass(), isset($context['json_ld_normalization_groups']) ? $context['json_ld_normalization_groups'] : $resource->getNormalizationGroups(), isset($context['json_ld_denormalization_groups']) ? $context['json_ld_denormalization_groups'] : $resource->getDenormalizationGroups(), isset($context['json_ld_validation_groups']) ? $context['json_ld_validation_groups'] : $resource->getValidationGroups());
 }
 /**
  * @param ResourceInterface $resource
  *
  * @return AttributeMetadataInterface
  */
 private function getIdentifierFromResource(ResourceInterface $resource)
 {
     $classMetadata = $this->classMetadataFactory->getMetadataFor($resource->getEntityClass(), $resource->getNormalizationGroups(), $resource->getDenormalizationGroups(), $resource->getValidationGroups());
     return $classMetadata->getIdentifier();
 }
 /**
  * {@inheritdoc}
  */
 public function warmUp($cacheDir)
 {
     foreach ($this->resourceCollection as $resource) {
         $this->classMetadataFactory->getMetadataFor($resource->getEntityClass(), $resource->getNormalizationGroups(), $resource->getDenormalizationGroups(), $resource->getValidationGroups());
     }
 }