1515
1616use ApiPlatform \Hydra \Collection ;
1717use ApiPlatform \Hydra \IriTemplate ;
18+ use ApiPlatform \Metadata \Property \Factory \PropertyMetadataFactoryInterface ;
19+ use ApiPlatform \Metadata \Property \Factory \PropertyNameCollectionFactoryInterface ;
1820use ApiPlatform \Metadata \ResourceClassResolverInterface ;
1921use ApiPlatform \Metadata \Util \TypeHelper ;
2022use Symfony \Component \JsonStreamer \Mapping \PropertyMetadata ;
@@ -26,6 +28,8 @@ final class WritePropertyMetadataLoader implements PropertyMetadataLoaderInterfa
2628 public function __construct (
2729 private readonly PropertyMetadataLoaderInterface $ loader ,
2830 private readonly ResourceClassResolverInterface $ resourceClassResolver ,
31+ private readonly PropertyNameCollectionFactoryInterface $ propertyNameCollectionFactory ,
32+ private readonly PropertyMetadataFactoryInterface $ propertyMetadataFactory ,
2933 ) {
3034 }
3135
@@ -47,23 +51,45 @@ public function load(string $className, array $options = [], array $context = []
4751 return $ properties ;
4852 }
4953
50- $ properties ['@id ' ] = new PropertyMetadata (
51- 'id ' , // virtual property
52- Type::mixed (), // virtual property
53- ['api_platform.jsonld.json_streamer.write.value_transformer.iri ' ],
54- );
54+ $ originalClassName = TypeHelper::getClassName ($ context ['original_type ' ]);
55+ $ hasIri = true ;
56+ $ virtualProperty = 'id ' ;
57+
58+ if ($ className !== $ originalClassName ) {
59+ foreach ($ this ->propertyNameCollectionFactory ->create ($ originalClassName ) as $ property ) {
60+ $ propertyMetadata = $ this ->propertyMetadataFactory ->create ($ originalClassName , $ property );
61+ if ($ propertyMetadata ->isIdentifier ()) {
62+ $ virtualProperty = $ property ;
63+ }
64+
65+ if ($ propertyMetadata ->getNativeType ()->isIdentifiedBy ($ className )) {
66+ $ hasIri = $ propertyMetadata ->getGenId ();
67+ $ virtualProperty = iterator_to_array ($ this ->propertyNameCollectionFactory ->create ($ className ))[0 ];
68+ }
69+ }
70+ }
71+
72+ if ($ hasIri ) {
73+ $ properties ['@id ' ] = new PropertyMetadata (
74+ $ virtualProperty , // virtual property
75+ Type::mixed (), // virtual property
76+ ['api_platform.jsonld.json_streamer.write.value_transformer.iri ' ],
77+ );
78+ }
5579
5680 $ properties ['@type ' ] = new PropertyMetadata (
57- ' id ' , // virtual property
81+ $ virtualProperty , // virtual property
5882 Type::mixed (), // virtual property
5983 ['api_platform.jsonld.json_streamer.write.value_transformer.type ' ],
6084 );
6185
62- $ originalClassName = TypeHelper::getClassName ($ context ['original_type ' ]);
86+ if ($ className !== $ originalClassName ) {
87+ return $ properties ;
88+ }
6389
6490 if (Collection::class === $ originalClassName || ($ this ->resourceClassResolver ->isResourceClass ($ originalClassName ) && !isset ($ context ['generated_classes ' ][Collection::class]))) {
6591 $ properties ['@context ' ] = new PropertyMetadata (
66- ' id ' , // virual property
92+ $ virtualProperty , // virual property
6793 Type::string (), // virtual property
6894 ['api_platform.jsonld.json_streamer.write.value_transformer.context ' ],
6995 );
0 commit comments