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); $metadata = $this->getHateoasMetadata($model); if (null === $metadata) { return; } $groupsExclusion = null !== $model->getGroups() ? new GroupsExclusionStrategy($model->getGroups()) : null; $schema->setType('object'); foreach ($metadata->getRelations() as $relation) { if (!$relation->getEmbedded() && !$relation->getHref()) { continue; } if (null !== $groupsExclusion && $relation->getExclusion()) { $item = new RelationPropertyMetadata($relation->getExclusion(), $relation); // filter groups if ($groupsExclusion->shouldSkipProperty($item, SerializationContext::create())) { continue; } } $name = $relation->getName(); $relationSchema = $schema->getProperties()->get($relation->getEmbedded() ? '_embedded' : '_links'); $properties = $relationSchema->getProperties(); $relationSchema->setReadOnly(true); $property = $properties->get($name); $property->setType('object'); if ($relation->getHref()) { $subProperties = $property->getProperties(); $hrefProp = $subProperties->get('href'); $hrefProp->setType('string'); $this->setAttributeProperties($relation, $subProperties); } } } 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; } } } }