Skip to content

Commit

Permalink
ability to disable hydra prop
Browse files Browse the repository at this point in the history
  • Loading branch information
soyuka committed Dec 29, 2024
1 parent 4c19bcd commit fe34348
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 85 deletions.
162 changes: 82 additions & 80 deletions src/Hydra/Serializer/DocumentationNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ public function normalize(mixed $object, ?string $format = null, array $context
}

$shortName = $resourceMetadata->getShortName();

$prefixedShortName = $resourceMetadata->getTypes()[0] ?? "#$shortName";

$this->populateEntrypointProperties($resourceMetadata, $shortName, $prefixedShortName, $entrypointProperties, $hydraPrefix, $resourceMetadataCollection);
$classes[] = $this->getClass($resourceClass, $resourceMetadata, $shortName, $prefixedShortName, $context, $hydraPrefix, $resourceMetadataCollection);
}
Expand All @@ -105,7 +105,7 @@ private function populateEntrypointProperties(ApiResource $resourceMetadata, str
'@id' => \sprintf('#Entrypoint/%s', lcfirst($shortName)),
'@type' => $hydraPrefix.'Link',
'domain' => '#Entrypoint',
'rdfs:label' => "get{$shortName}Collection",
'title' => "{$shortName}CollectionEntrypoint",
'rdfs:range' => [
['@id' => $hydraPrefix.'Collection'],
[
Expand All @@ -117,7 +117,8 @@ private function populateEntrypointProperties(ApiResource $resourceMetadata, str
],
$hydraPrefix.'supportedOperation' => $hydraCollectionOperations,
],
$hydraPrefix.'title' => "The collection of $shortName resources",
$hydraPrefix.'title' => "get{$shortName}Collection",
$hydraPrefix.'description' => "The collection of $shortName resources",
$hydraPrefix.'readable' => true,
$hydraPrefix.'writeable' => false,
];
Expand All @@ -140,7 +141,6 @@ private function getClass(string $resourceClass, ApiResource $resourceMetadata,
$class = [
'@id' => $prefixedShortName,
'@type' => $hydraPrefix.'Class',
'rdfs:label' => $shortName,
$hydraPrefix.'title' => $shortName,
$hydraPrefix.'supportedProperty' => $this->getHydraProperties($resourceClass, $resourceMetadata, $shortName, $prefixedShortName, $context, $hydraPrefix),
$hydraPrefix.'supportedOperation' => $this->getHydraOperations(false, $resourceMetadataCollection, $hydraPrefix),
Expand Down Expand Up @@ -232,6 +232,10 @@ private function getHydraProperties(string $resourceClass, ApiResource $resource
$propertyName = $this->nameConverter->normalize($propertyName, $class, self::FORMAT, $context);
}

if (false === $propertyMetadata->getHydra()) {
continue;
}

$properties[] = $this->getProperty($propertyMetadata, $propertyName, $prefixedShortName, $shortName, $hydraPrefix);
}
}
Expand All @@ -254,6 +258,7 @@ private function getHydraOperations(bool $collection, ?ResourceMetadataCollectio
if (('POST' === $operation->getMethod() || $operation instanceof CollectionOperationInterface) !== $collection) {
continue;
}

$hydraOperations[] = $this->getHydraOperation($operation, $operation->getShortName(), $hydraPrefix);
}
}
Expand Down Expand Up @@ -283,50 +288,46 @@ private function getHydraOperation(HttpOperation $operation, string $prefixedSho
if ('GET' === $method && $operation instanceof CollectionOperationInterface) {
$hydraOperation += [
'@type' => [$hydraPrefix.'Operation', 'schema:FindAction'],
$hydraPrefix.'title' => "Retrieves the collection of $shortName resources.",
$hydraPrefix.'description' => "Retrieves the collection of $shortName resources.",
'returns' => null === $outputClass ? 'owl:Nothing' : $hydraPrefix.'Collection',
];
} elseif ('GET' === $method) {
$hydraOperation += [
'@type' => [$hydraPrefix.'Operation', 'schema:FindAction'],
$hydraPrefix.'title' => "Retrieves a $shortName resource.",
$hydraPrefix.'description' => "Retrieves a $shortName resource.",
'returns' => null === $outputClass ? 'owl:Nothing' : $prefixedShortName,
];
} elseif ('PATCH' === $method) {
$hydraOperation += [
'@type' => $hydraPrefix.'Operation',
$hydraPrefix.'title' => "Updates the $shortName resource.",
$hydraPrefix.'description' => "Updates the $shortName resource.",
'returns' => null === $outputClass ? 'owl:Nothing' : $prefixedShortName,
'expects' => null === $inputClass ? 'owl:Nothing' : $prefixedShortName,
];
} elseif ('POST' === $method) {
$hydraOperation += [
'@type' => [$hydraPrefix.'Operation', 'schema:CreateAction'],
$hydraPrefix.'title' => "Creates a $shortName resource.",
$hydraPrefix.'description' => "Creates a $shortName resource.",
'returns' => null === $outputClass ? 'owl:Nothing' : $prefixedShortName,
'expects' => null === $inputClass ? 'owl:Nothing' : $prefixedShortName,
];
} elseif ('PUT' === $method) {
$hydraOperation += [
'@type' => [$hydraPrefix.'Operation', 'schema:ReplaceAction'],
$hydraPrefix.'title' => "Replaces the $shortName resource.",
$hydraPrefix.'description' => "Replaces the $shortName resource.",
'returns' => null === $outputClass ? 'owl:Nothing' : $prefixedShortName,
'expects' => null === $inputClass ? 'owl:Nothing' : $prefixedShortName,
];
} elseif ('DELETE' === $method) {
$hydraOperation += [
'@type' => [$hydraPrefix.'Operation', 'schema:DeleteAction'],
$hydraPrefix.'title' => "Deletes the $shortName resource.",
$hydraPrefix.'description' => "Deletes the $shortName resource.",
'returns' => 'owl:Nothing',
];
}

$hydraOperation[$hydraPrefix.'method'] ?? $hydraOperation[$hydraPrefix.'method'] = $method;

if (!isset($hydraOperation['rdfs:label'])) {
// we know that this name is unique
$hydraOperation['rdfs:label'] = $operation->getName();
}
$hydraOperation[$hydraPrefix.'method'] ??= $method;
$hydraOperation[$hydraPrefix.'title'] ??= strtolower($method) . $shortName . ($operation instanceof CollectionOperationInterface ? 'Collection' : '');

ksort($hydraOperation);

Expand Down Expand Up @@ -435,77 +436,78 @@ private function getClasses(array $entrypointProperties, array $classes, string
$classes[] = [
'@id' => '#Entrypoint',
'@type' => $hydraPrefix.'Class',
$hydraPrefix.'title' => 'The API entrypoint',
$hydraPrefix.'title' => 'Entrypoint',
$hydraPrefix.'description' => 'API Entrypoint',
$hydraPrefix.'supportedProperty' => $entrypointProperties,
$hydraPrefix.'supportedOperation' => [
'@type' => $hydraPrefix.'Operation',
$hydraPrefix.'method' => 'GET',
'title' => 'The API entrypoint.',
'rdfs:label' => 'getEntrypoint',
'returns' => 'EntryPoint',
$hydraPrefix.'title' => 'Entrypoint',
'rdfs:label' => 'index',
$hydraPrefix.'returns' => 'EntryPoint',
],
];

// Constraint violation
$classes[] = [
'@id' => '#ConstraintViolation',
'@type' => $hydraPrefix.'Class',
$hydraPrefix.'title' => 'A constraint violation',
$hydraPrefix.'supportedProperty' => [
[
'@type' => $hydraPrefix.'SupportedProperty',
$hydraPrefix.'property' => [
'@id' => '#ConstraintViolation/propertyPath',
'@type' => 'rdf:Property',
'rdfs:label' => 'propertyPath',
'domain' => '#ConstraintViolation',
'range' => 'xmls:string',
],
$hydraPrefix.'title' => 'propertyPath',
$hydraPrefix.'description' => 'The property path of the violation',
$hydraPrefix.'readable' => true,
$hydraPrefix.'writeable' => false,
],
[
'@type' => $hydraPrefix.'SupportedProperty',
$hydraPrefix.'property' => [
'@id' => '#ConstraintViolation/message',
'@type' => 'rdf:Property',
'rdfs:label' => 'message',
'domain' => '#ConstraintViolation',
'range' => 'xmls:string',
],
$hydraPrefix.'title' => 'message',
$hydraPrefix.'description' => 'The message associated with the violation',
$hydraPrefix.'readable' => true,
$hydraPrefix.'writeable' => false,
],
],
];

// Constraint violation list
$classes[] = [
'@id' => '#ConstraintViolationList',
'@type' => $hydraPrefix.'Class',
'subClassOf' => $hydraPrefix.'Error',
$hydraPrefix.'title' => 'A constraint violation list',
$hydraPrefix.'supportedProperty' => [
[
'@type' => $hydraPrefix.'SupportedProperty',
$hydraPrefix.'property' => [
'@id' => '#ConstraintViolationList/violations',
'@type' => 'rdf:Property',
'rdfs:label' => 'violations',
'domain' => '#ConstraintViolationList',
'range' => '#ConstraintViolation',
],
$hydraPrefix.'title' => 'violations',
$hydraPrefix.'description' => 'The violations',
$hydraPrefix.'readable' => true,
$hydraPrefix.'writeable' => false,
],
],
];
// $classes[] = [
// '@id' => '#ConstraintViolation',
// '@type' => $hydraPrefix.'Class',
// $hydraPrefix.'title' => 'A constraint violation',
// $hydraPrefix.'supportedProperty' => [
// [
// '@type' => $hydraPrefix.'SupportedProperty',
// $hydraPrefix.'property' => [
// '@id' => '#ConstraintViolation/propertyPath',
// '@type' => 'rdf:Property',
// 'rdfs:label' => 'propertyPath',
// 'domain' => '#ConstraintViolation',
// 'range' => 'xmls:string',
// ],
// $hydraPrefix.'title' => 'propertyPath',
// $hydraPrefix.'description' => 'The property path of the violation',
// $hydraPrefix.'readable' => true,
// $hydraPrefix.'writeable' => false,
// ],
// [
// '@type' => $hydraPrefix.'SupportedProperty',
// $hydraPrefix.'property' => [
// '@id' => '#ConstraintViolation/message',
// '@type' => 'rdf:Property',
// 'rdfs:label' => 'message',
// 'domain' => '#ConstraintViolation',
// 'range' => 'xmls:string',
// ],
// $hydraPrefix.'title' => 'message',
// $hydraPrefix.'description' => 'The message associated with the violation',
// $hydraPrefix.'readable' => true,
// $hydraPrefix.'writeable' => false,
// ],
// ],
// ];
//
// // Constraint violation list
// $classes[] = [
// '@id' => '#ConstraintViolationList',
// '@type' => $hydraPrefix.'Class',
// 'subClassOf' => $hydraPrefix.'Error',
// $hydraPrefix.'title' => 'A constraint violation list',
// $hydraPrefix.'supportedProperty' => [
// [
// '@type' => $hydraPrefix.'SupportedProperty',
// $hydraPrefix.'property' => [
// '@id' => '#ConstraintViolationList/violations',
// '@type' => 'rdf:Property',
// 'rdfs:label' => 'violations',
// 'domain' => '#ConstraintViolationList',
// 'range' => '#ConstraintViolation',
// ],
// $hydraPrefix.'title' => 'violations',
// $hydraPrefix.'description' => 'The violations',
// $hydraPrefix.'readable' => true,
// $hydraPrefix.'writeable' => false,
// ],
// ],
// ];

return $classes;
}
Expand All @@ -526,7 +528,7 @@ private function getProperty(ApiProperty $propertyMetadata, string $propertyName
$propertyData = ($propertyMetadata->getJsonldContext()[$hydraPrefix.'property'] ?? []) + [
'@id' => $iri,
'@type' => false === $propertyMetadata->isReadableLink() ? $hydraPrefix.'Link' : 'rdf:Property',
'rdfs:label' => $propertyName,
'title' => $propertyName,
'domain' => $prefixedShortName,
];

Expand Down
21 changes: 19 additions & 2 deletions src/Metadata/ApiProperty.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
*
* @author Kévin Dunglas <[email protected]>
*/
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::TARGET_PARAMETER | \Attribute::TARGET_CLASS_CONSTANT | \Attribute::TARGET_CLASS)]
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::TARGET_PARAMETER | \Attribute::TARGET_CLASS_CONSTANT | \Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)]
final class ApiProperty
{
private ?array $types;
Expand Down Expand Up @@ -216,6 +216,10 @@ public function __construct(
private ?string $property = null,
private ?string $policy = null,
array|Context|Groups|Ignore|SerializedName|SerializedPath|MaxDepth|null $serialize = null,
/**
* Whether to document this property as a hydra:supportedProperty
*/
private ?bool $hydra = null,
private array $extraProperties = [],
) {
$this->types = \is_string($types) ? (array) $types : $types;
Expand Down Expand Up @@ -517,7 +521,7 @@ public function withSchema(array $schema = []): self
return $self;
}

public function withInitializable(?bool $initializable): self
public function withInitializable(bool $initializable): self
{
$self = clone $this;
$self->initializable = $initializable;
Expand Down Expand Up @@ -626,4 +630,17 @@ public function withSerialize(array|Context|Groups|Ignore|SerializedName|Seriali

return $self;
}

public function getHydra(): ?bool
{
return $this->hydra;
}

public function withHydra(bool $hydra): static
{
$self = clone $this;
$self->hydra = $hydra;

return $self;
}
}
2 changes: 2 additions & 0 deletions src/Metadata/Error.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ public function __construct(
$provider = null,
$processor = null,
?OptionsInterface $stateOptions = null,
?bool $hideHydraOperation = null,
array $extraProperties = [],
) {
parent::__construct(
Expand Down Expand Up @@ -169,6 +170,7 @@ class: $class,
provider: $provider,
processor: $processor,
stateOptions: $stateOptions,
hideHydraOperation: $hideHydraOperation,
extraProperties: $extraProperties,
);
}
Expand Down
Loading

0 comments on commit fe34348

Please sign in to comment.