Skip to content

Commit dea48d6

Browse files
committed
1 parent 47828e9 commit dea48d6

File tree

4 files changed

+41
-28
lines changed

4 files changed

+41
-28
lines changed

src/Hydra/JsonSchema/SchemaFactory.php

+29-22
Original file line numberDiff line numberDiff line change
@@ -37,37 +37,43 @@ final class SchemaFactory implements SchemaFactoryInterface, SchemaFactoryAwareI
3737
use SchemaUriPrefixTrait;
3838

3939
private const ITEM_BASE_SCHEMA_NAME = 'HydraItemBaseSchema';
40+
private const ITEM_BASE_SCHEMA_OUTPUT_NAME = 'HydraOutputBaseSchema';
4041
private const COLLECTION_BASE_SCHEMA_NAME = 'HydraCollectionBaseSchema';
4142
private const BASE_PROP = [
42-
'readOnly' => true,
4343
'type' => 'string',
4444
];
4545
private const BASE_PROPS = [
4646
'@id' => self::BASE_PROP,
4747
'@type' => self::BASE_PROP,
4848
];
49-
private const BASE_ROOT_PROPS = [
50-
'@context' => [
51-
'readOnly' => true,
52-
'oneOf' => [
53-
['type' => 'string'],
54-
[
55-
'type' => 'object',
56-
'properties' => [
57-
'@vocab' => [
58-
'type' => 'string',
59-
],
60-
'hydra' => [
61-
'type' => 'string',
62-
'enum' => [ContextBuilder::HYDRA_NS],
49+
private const ITEM_BASE_SCHEMA = [
50+
'type' => 'object',
51+
'properties' => [
52+
'@context' => [
53+
'oneOf' => [
54+
['type' => 'string'],
55+
[
56+
'type' => 'object',
57+
'properties' => [
58+
'@vocab' => [
59+
'type' => 'string',
60+
],
61+
'hydra' => [
62+
'type' => 'string',
63+
'enum' => [ContextBuilder::HYDRA_NS],
64+
],
6365
],
66+
'required' => ['@vocab', 'hydra'],
67+
'additionalProperties' => true,
6468
],
65-
'required' => ['@vocab', 'hydra'],
66-
'additionalProperties' => true,
6769
],
68-
],
70+
] + self::BASE_PROPS,
6971
],
70-
] + self::BASE_PROPS;
72+
];
73+
74+
private const ITEM_BASE_SCHEMA_OUTPUT = [
75+
'required' => ['@id', '@type'],
76+
] + self::ITEM_BASE_SCHEMA;
7177

7278
/**
7379
* @param array<string, mixed> $defaultContext
@@ -126,13 +132,14 @@ public function buildSchema(string $className, string $format = 'jsonld', string
126132

127133
$key = $schema->getRootDefinitionKey() ?? $collectionKey;
128134

129-
if (!isset($definitions[self::ITEM_BASE_SCHEMA_NAME])) {
130-
$definitions[self::ITEM_BASE_SCHEMA_NAME] = ['type' => 'object', 'properties' => self::BASE_ROOT_PROPS];
135+
$name = Schema::TYPE_OUTPUT === $type ? self::ITEM_BASE_SCHEMA_NAME : self::ITEM_BASE_SCHEMA_OUTPUT_NAME;
136+
if (!isset($definitions[$name])) {
137+
$definitions[$name] = Schema::TYPE_OUTPUT === $type ? self::ITEM_BASE_SCHEMA_OUTPUT : self::ITEM_BASE_SCHEMA;
131138
}
132139

133140
$definitions[$definitionName] = [
134141
'allOf' => [
135-
['$ref' => $prefix.self::ITEM_BASE_SCHEMA_NAME],
142+
['$ref' => $prefix.$name],
136143
['$ref' => $prefix.$key],
137144
],
138145
];

src/JsonApi/JsonSchema/SchemaFactory.php

+10-5
Original file line numberDiff line numberDiff line change
@@ -317,15 +317,20 @@ private function buildDefinitionPropertiesSchema(string $key, string $className,
317317
}
318318

319319
if ($required = $definitions[$key]['required'] ?? null) {
320-
foreach ($required as $require) {
321-
if (isset($replacement['attributes']['properties'][$require])) {
322-
$replacement['attributes']['required'][] = $require;
323-
continue;
324-
}
320+
foreach ($required as $i => $require) {
325321
if (isset($relationships[$require])) {
326322
$replacement['relationships']['required'][] = $require;
323+
unset($required[$i]);
327324
}
328325
}
326+
327+
$replacement['attributes'] = [
328+
'allOf' => [
329+
$replacement['attributes'],
330+
['type' => 'object', 'required' => $required],
331+
],
332+
];
333+
329334
unset($definitions[$key]['required']);
330335
}
331336

src/JsonSchema/SchemaFactory.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ final class SchemaFactory implements SchemaFactoryInterface, SchemaFactoryAwareI
4040
public const FORCE_SUBSCHEMA = '_api_subschema_force_readable_link';
4141
public const OPENAPI_DEFINITION_NAME = 'openapi_definition_name';
4242

43-
public function __construct(ResourceMetadataCollectionFactoryInterface $resourceMetadataFactory, private readonly PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, private readonly PropertyMetadataFactoryInterface $propertyMetadataFactory, private readonly ?NameConverterInterface $nameConverter = null, ?ResourceClassResolverInterface $resourceClassResolver = null, private readonly ?array $distinctFormats = null, private ?DefinitionNameFactoryInterface $definitionNameFactory = null)
43+
public function __construct(ResourceMetadataCollectionFactoryInterface $resourceMetadataFactory, private readonly PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, private readonly PropertyMetadataFactoryInterface $propertyMetadataFactory, private readonly ?NameConverterInterface $nameConverter = null, ?ResourceClassResolverInterface $resourceClassResolver = null, ?array $distinctFormats = null, private ?DefinitionNameFactoryInterface $definitionNameFactory = null)
4444
{
4545
if (!$definitionNameFactory) {
4646
$this->definitionNameFactory = new DefinitionNameFactory($distinctFormats);

tests/Symfony/Bundle/DependencyInjection/ConfigurationTest.php

+1
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ private function runDefaultConfigTests(array $doctrineIntegrationsToLoad = ['orm
216216
'license' => [
217217
'name' => null,
218218
'url' => null,
219+
'identifier' => null,
219220
],
220221
'swagger_ui_extra_configuration' => [],
221222
'overrideResponses' => true,

0 commit comments

Comments
 (0)