17
17
use ApiPlatform \Api \ResourceClassResolverInterface as LegacyResourceClassResolverInterface ;
18
18
use ApiPlatform \JsonLd \AnonymousContextBuilderInterface ;
19
19
use ApiPlatform \JsonLd \ContextBuilderInterface ;
20
+ use ApiPlatform \Metadata \Exception \ItemNotFoundException ;
20
21
use ApiPlatform \Metadata \HttpOperation ;
21
22
use ApiPlatform \Metadata \IriConverterInterface ;
22
23
use ApiPlatform \Metadata \Property \Factory \PropertyMetadataFactoryInterface ;
23
24
use ApiPlatform \Metadata \Property \Factory \PropertyNameCollectionFactoryInterface ;
25
+ use ApiPlatform \Metadata \Put ;
24
26
use ApiPlatform \Metadata \Resource \Factory \ResourceMetadataCollectionFactoryInterface ;
25
27
use ApiPlatform \Metadata \ResourceAccessCheckerInterface ;
26
28
use ApiPlatform \Metadata \ResourceClassResolverInterface ;
@@ -47,6 +49,29 @@ final class ItemNormalizer extends AbstractItemNormalizer
47
49
use JsonLdContextTrait;
48
50
49
51
public const FORMAT = 'jsonld ' ;
52
+ private const JSONLD_KEYWORDS = [
53
+ '@context ' ,
54
+ '@direction ' ,
55
+ '@graph ' ,
56
+ '@id ' ,
57
+ '@import ' ,
58
+ '@included ' ,
59
+ '@index ' ,
60
+ '@json ' ,
61
+ '@language ' ,
62
+ '@list ' ,
63
+ '@nest ' ,
64
+ '@none ' ,
65
+ '@prefix ' ,
66
+ '@propagate ' ,
67
+ '@protected ' ,
68
+ '@reverse ' ,
69
+ '@set ' ,
70
+ '@type ' ,
71
+ '@value ' ,
72
+ '@version ' ,
73
+ '@vocab ' ,
74
+ ];
50
75
51
76
public function __construct (ResourceMetadataCollectionFactoryInterface $ resourceMetadataCollectionFactory , PropertyNameCollectionFactoryInterface $ propertyNameCollectionFactory , PropertyMetadataFactoryInterface $ propertyMetadataFactory , IriConverterInterface |LegacyIriConverterInterface $ iriConverter , ResourceClassResolverInterface |LegacyResourceClassResolverInterface $ resourceClassResolver , private readonly ContextBuilderInterface $ contextBuilder , ?PropertyAccessorInterface $ propertyAccessor = null , ?NameConverterInterface $ nameConverter = null , ?ClassMetadataFactoryInterface $ classMetadataFactory = null , array $ defaultContext = [], ?ResourceAccessCheckerInterface $ resourceAccessChecker = null , protected ?TagCollectorInterface $ tagCollector = null )
52
77
{
@@ -148,9 +173,26 @@ public function denormalize(mixed $data, string $class, ?string $format = null,
148
173
throw new NotNormalizableValueException ('Update is not allowed for this operation. ' );
149
174
}
150
175
151
- $ context [self ::OBJECT_TO_POPULATE ] = $ this ->iriConverter ->getResourceFromIri ($ data ['@id ' ], $ context + ['fetch_data ' => true ]);
176
+ try {
177
+ $ context [self ::OBJECT_TO_POPULATE ] = $ this ->iriConverter ->getResourceFromIri ($ data ['@id ' ], $ context + ['fetch_data ' => true ], $ context ['operation ' ] ?? null );
178
+ } catch (ItemNotFoundException $ e ) {
179
+ $ operation = $ context ['operation ' ] ?? null ;
180
+ if (!($ operation instanceof Put && ($ operation ->getExtraProperties ()['standard_put ' ] ?? false ))) {
181
+ throw $ e ;
182
+ }
183
+ }
152
184
}
153
185
154
186
return parent ::denormalize ($ data , $ class , $ format , $ context );
155
187
}
188
+
189
+ protected function getAllowedAttributes (string |object $ classOrObject , array $ context , bool $ attributesAsString = false ): array |bool
190
+ {
191
+ $ allowedAttributes = parent ::getAllowedAttributes ($ classOrObject , $ context , $ attributesAsString );
192
+ if (\is_array ($ allowedAttributes ) && ($ context ['api_denormalize ' ] ?? false )) {
193
+ $ allowedAttributes = array_merge ($ allowedAttributes , self ::JSONLD_KEYWORDS );
194
+ }
195
+
196
+ return $ allowedAttributes ;
197
+ }
156
198
}
0 commit comments