2121use ApiPlatform \Exception \RuntimeException ;
2222use ApiPlatform \GraphQl \Subscription \MercureSubscriptionIriGeneratorInterface as GraphQlMercureSubscriptionIriGeneratorInterface ;
2323use ApiPlatform \GraphQl \Subscription \SubscriptionManagerInterface as GraphQlSubscriptionManagerInterface ;
24+ use ApiPlatform \Metadata \HttpOperation ;
2425use ApiPlatform \Metadata \Resource \Factory \ResourceMetadataCollectionFactoryInterface ;
2526use ApiPlatform \Symfony \Messenger \DispatchTrait ;
2627use ApiPlatform \Util \ResourceClassInfoTrait ;
@@ -63,7 +64,7 @@ final class PublishMercureUpdatesListener
6364 /**
6465 * @param array<string, string[]|string> $formats
6566 */
66- public function __construct (ResourceClassResolverInterface $ resourceClassResolver , private readonly IriConverterInterface $ iriConverter , ResourceMetadataCollectionFactoryInterface $ resourceMetadataFactory , private readonly SerializerInterface $ serializer , private readonly array $ formats , MessageBusInterface $ messageBus = null , private readonly ?HubRegistry $ hubRegistry = null , private readonly ?GraphQlSubscriptionManagerInterface $ graphQlSubscriptionManager = null , private readonly ?GraphQlMercureSubscriptionIriGeneratorInterface $ graphQlMercureSubscriptionIriGenerator = null , ExpressionLanguage $ expressionLanguage = null )
67+ public function __construct (ResourceClassResolverInterface $ resourceClassResolver , private readonly IriConverterInterface $ iriConverter , ResourceMetadataCollectionFactoryInterface $ resourceMetadataFactory , private readonly SerializerInterface $ serializer , private readonly array $ formats , MessageBusInterface $ messageBus = null , private readonly ?HubRegistry $ hubRegistry = null , private readonly ?GraphQlSubscriptionManagerInterface $ graphQlSubscriptionManager = null , private readonly ?GraphQlMercureSubscriptionIriGeneratorInterface $ graphQlMercureSubscriptionIriGenerator = null , ExpressionLanguage $ expressionLanguage = null , private bool $ includeType = false )
6768 {
6869 if (null === $ messageBus && null === $ hubRegistry ) {
6970 throw new InvalidArgumentException ('A message bus or a hub registry must be provided. ' );
@@ -84,6 +85,10 @@ public function __construct(ResourceClassResolverInterface $resourceClassResolve
8485 new ExpressionFunction ('iri ' , static fn (string $ apiResource , int $ referenceType = UrlGeneratorInterface::ABS_URL ): string => sprintf ('iri(%s, %d) ' , $ apiResource , $ referenceType ), static fn (array $ arguments , $ apiResource , int $ referenceType = UrlGeneratorInterface::ABS_URL ): string => $ iriConverter ->getIriFromResource ($ apiResource , $ referenceType ))
8586 );
8687 }
88+
89+ if (false === $ this ->includeType ) {
90+ trigger_deprecation ('api-platform/core ' , '3.1 ' , 'Having mercure.include_type (always include @type in Mercure updates, even delete ones) set to false in the configuration is deprecated. It will be true by default in API Platform 4.0. ' );
91+ }
8792 }
8893
8994 /**
@@ -150,8 +155,9 @@ private function storeObjectToPublish(object $object, string $property): void
150155 return ;
151156 }
152157
158+ $ operation = $ this ->resourceMetadataFactory ->create ($ resourceClass )->getOperation ();
153159 try {
154- $ options = $ this -> resourceMetadataFactory -> create ( $ resourceClass )-> getOperation () ->getMercure () ?? false ;
160+ $ options = $ operation ->getMercure () ?? false ;
155161 } catch (OperationNotFoundException ) {
156162 return ;
157163 }
@@ -208,9 +214,15 @@ private function storeObjectToPublish(object $object, string $property): void
208214 }
209215
210216 if ('deletedObjects ' === $ property ) {
217+ $ types = $ operation instanceof HttpOperation ? $ operation ->getTypes () : null ;
218+ if (null === $ types ) {
219+ $ types = [$ operation ->getShortName ()];
220+ }
221+
211222 $ this ->deletedObjects [(object ) [
212223 'id ' => $ this ->iriConverter ->getIriFromResource ($ object ),
213224 'iri ' => $ this ->iriConverter ->getIriFromResource ($ object , UrlGeneratorInterface::ABS_URL ),
225+ 'type ' => 1 === \count ($ types ) ? $ types [0 ] : $ types ,
214226 ]] = $ options ;
215227
216228 return ;
@@ -222,12 +234,12 @@ private function storeObjectToPublish(object $object, string $property): void
222234 private function publishUpdate (object $ object , array $ options , string $ type ): void
223235 {
224236 if ($ object instanceof \stdClass) {
225- // By convention, if the object has been deleted, we send only its IRI.
237+ // By convention, if the object has been deleted, we send only its IRI and its type .
226238 // This may change in the feature, because it's not JSON Merge Patch compliant,
227239 // and I'm not a fond of this approach.
228240 $ iri = $ options ['topics ' ] ?? $ object ->iri ;
229241 /** @var string $data */
230- $ data = json_encode (['@id ' => $ object ->id ], \JSON_THROW_ON_ERROR );
242+ $ data = json_encode (['@id ' => $ object ->id ] + ( $ this -> includeType ? [ ' @type ' => $ object -> type ] : []) , \JSON_THROW_ON_ERROR );
231243 } else {
232244 $ resourceClass = $ this ->getObjectClass ($ object );
233245 $ context = $ options ['normalization_context ' ] ?? $ this ->resourceMetadataFactory ->create ($ resourceClass )->getOperation ()->getNormalizationContext () ?? [];
0 commit comments