Skip to content

Commit 7ceddfd

Browse files
committed
Fix form submit @id using IriConverter instead of string search
Replaces the brittle str_contains/'\/submit' JSON search in onPostRespond with IriConverterInterface::getIriFromResource() to get the canonical Form IRI directly. getData() already guards against non-Form results (e.g. User from registration), so the correction only fires when the response is still a Form entity with a /submit-suffixed @id.
1 parent ecfc8de commit 7ceddfd

2 files changed

Lines changed: 13 additions & 5 deletions

File tree

src/EventListener/Api/FormApiEventListener.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Silverback\ApiComponentsBundle\EventListener\Api;
1313

14+
use ApiPlatform\Metadata\IriConverterInterface;
1415
use Silverback\ApiComponentsBundle\Entity\Component\Form;
1516
use Silverback\ApiComponentsBundle\Factory\Form\FormViewFactory;
1617
use Silverback\ApiComponentsBundle\Helper\Form\FormSubmitHelper;
@@ -31,12 +32,14 @@ class FormApiEventListener
3132
private SerializeFormatResolver $serializeFormatResolver;
3233
private SerializerInterface $serializer;
3334
private FormViewFactory $formViewFactory;
35+
private IriConverterInterface $iriConverter;
3436

3537
public function __construct(
3638
FormSubmitHelper $formSubmitHelper,
3739
SerializeFormatResolver $serializeFormatResolver,
3840
SerializerInterface $serializer,
3941
FormViewFactory $formViewFactory,
42+
IriConverterInterface $iriConverter,
4043
) {
4144
if (!$serializer instanceof DecoderInterface) {
4245
throw new \InvalidArgumentException(\sprintf('$serializer must be also be an instance of %s', DecoderInterface::class));
@@ -45,6 +48,7 @@ public function __construct(
4548
$this->serializeFormatResolver = $serializeFormatResolver;
4649
$this->serializer = $serializer;
4750
$this->formViewFactory = $formViewFactory;
51+
$this->iriConverter = $iriConverter;
4852
}
4953

5054
public function onPreSerialize(ViewEvent $event): void
@@ -109,13 +113,16 @@ public function onPostRespond(ResponseEvent $event): void
109113
}
110114

111115
// AP4 uses the submit operation's uriTemplate to generate @id, giving /{uuid}/submit.
112-
// Strip the suffix so @id always points to the canonical resource IRI.
116+
// Use the IRI converter to get the canonical IRI and correct @id when it differs.
113117
$content = $response->getContent();
114-
if ($content && str_contains($content, '\/submit"')) {
118+
if ($content) {
115119
$decoded = json_decode($content, true);
116-
if (isset($decoded['@id']) && str_ends_with($decoded['@id'], '/submit')) {
117-
$decoded['@id'] = substr($decoded['@id'], 0, -\strlen('/submit'));
118-
$response->setContent(json_encode($decoded));
120+
if (isset($decoded['@id'])) {
121+
$canonicalIri = $this->iriConverter->getIriFromResource($data);
122+
if ($decoded['@id'] !== $canonicalIri) {
123+
$decoded['@id'] = $canonicalIri;
124+
$response->setContent(json_encode($decoded));
125+
}
119126
}
120127
}
121128
}

src/Resources/config/services.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,7 @@
496496
new Reference(SerializeFormatResolver::class),
497497
new Reference(SerializerInterface::class),
498498
new Reference(FormViewFactory::class),
499+
new Reference(IriConverterInterface::class),
499500
]
500501
)
501502
->tag('kernel.event_listener', ['event' => ViewEvent::class, 'priority' => EventPriorities::PRE_SERIALIZE, 'method' => 'onPreSerialize'])

0 commit comments

Comments
 (0)