factory = $factory; $this->JMSModelDescriber = $JMSModelDescriber; } public function setModelRegistry(ModelRegistry $modelRegistry) { $this->modelRegistry = $modelRegistry; $this->JMSModelDescriber->setModelRegistry($modelRegistry); } /** * {@inheritdoc} */ public function describe(Model $model, Schema $schema) { $this->JMSModelDescriber->describe($model, $schema); /** * @var ClassMetadata */ $metadata = $this->getHateoasMetadata($model); if (null === $metadata) { return; } $schema->setType('object'); $context = $this->JMSModelDescriber->getSerializationContext($model); foreach ($metadata->getRelations() as $relation) { if (!$relation->getEmbedded() && !$relation->getHref()) { continue; } $item = new RelationPropertyMetadata($relation->getExclusion(), $relation); if (null !== $context->getExclusionStrategy() && $context->getExclusionStrategy()->shouldSkipProperty($item, $context)) { continue; } $context->pushPropertyMetadata($item); $embedded = $relation->getEmbedded(); $relationSchema = $schema->getProperties()->get($embedded ? '_embedded' : '_links'); $properties = $relationSchema->getProperties(); $relationSchema->setReadOnly(true); $name = $relation->getName(); $property = $properties->get($name); if ($embedded && method_exists($embedded, 'getType') && $embedded->getType()) { $this->JMSModelDescriber->describeItem($embedded->getType(), $property, $context); } else { $property->setType('object'); } if ($relation->getHref()) { $subProperties = $property->getProperties(); $hrefProp = $subProperties->get('href'); $hrefProp->setType('string'); $this->setAttributeProperties($relation, $subProperties); } $context->popPropertyMetadata(); } } private function getHateoasMetadata(Model $model) { $className = $model->getType()->getClassName(); try { if ($metadata = $this->factory->getMetadataForClass($className)) { return $metadata; } } catch (\ReflectionException $e) { } return null; } /** * {@inheritdoc} */ public function supports(Model $model): bool { return $this->JMSModelDescriber->supports($model) || null !== $this->getHateoasMetadata($model); } private function setAttributeProperties(Relation $relation, $subProperties) { foreach ($relation->getAttributes() as $attribute => $value) { $subSubProp = $subProperties->get($attribute); switch (gettype($value)) { case 'integer' : $subSubProp->setType('integer'); $subSubProp->setDefault($value); break; case 'double': case 'float': $subSubProp->setType('number'); $subSubProp->setDefault($value); break; case 'boolean': $subSubProp->setType('boolean'); $subSubProp->setDefault($value); break; case 'string': $subSubProp->setType('string'); $subSubProp->setDefault($value); break; } } } }