From 359ecbff6b3f02438a0b980f232b0b521a3fdc34 Mon Sep 17 00:00:00 2001 From: Michel Bade Date: Fri, 18 Sep 2026 13:40:10 +0200 Subject: [PATCH] perf: reuse parsed response --- src/Context/ContextResolver.php | 56 +++++++++++++++------------ tests/Context/ContextResolverTest.php | 12 ++++++ 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/Context/ContextResolver.php b/src/Context/ContextResolver.php index b5a6444..83da909 100644 --- a/src/Context/ContextResolver.php +++ b/src/Context/ContextResolver.php @@ -6,6 +6,7 @@ use DateTimeImmutable; use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ServerRequestInterface; use Shopware\App\SDK\Context\ActionButton\ActionButtonAction; use Shopware\App\SDK\Context\Cart\Cart; use Shopware\App\SDK\Context\Gateway\Checkout\CheckoutGatewayAction; @@ -47,8 +48,7 @@ public function __construct( */ public function assembleWebhook(RequestInterface $request, ShopInterface $shop): WebhookAction { - $body = \json_decode($request->getBody()->getContents(), true, flags: \JSON_THROW_ON_ERROR); - $request->getBody()->rewind(); + $body = $this->getBody($request); if (!\is_array($body) || !isset($body['source']) || !\is_array($body['source'])) { throw new MalformedWebhookBodyException(); @@ -65,8 +65,7 @@ public function assembleWebhook(RequestInterface $request, ShopInterface $shop): public function assembleActionButton(RequestInterface $request, ShopInterface $shop): ActionButtonAction { - $body = \json_decode($request->getBody()->getContents(), true, flags: \JSON_THROW_ON_ERROR); - $request->getBody()->rewind(); + $body = $this->getBody($request); if (!\is_array($body) || !isset($body['source']) || !\is_array($body['source'])) { throw new MalformedWebhookBodyException(); @@ -110,8 +109,7 @@ public function assembleModule(RequestInterface $request, ShopInterface $shop): public function assembleTaxProvider(RequestInterface $request, ShopInterface $shop): TaxProviderAction { - $body = \json_decode($request->getBody()->getContents(), true, flags: \JSON_THROW_ON_ERROR); - $request->getBody()->rewind(); + $body = $this->getBody($request); if (!\is_array($body) || !isset($body['source']) || !\is_array($body['source'])) { throw new MalformedWebhookBodyException(); @@ -127,8 +125,7 @@ public function assembleTaxProvider(RequestInterface $request, ShopInterface $sh public function assemblePaymentPay(RequestInterface $request, ShopInterface $shop): PaymentPayAction { - $body = \json_decode($request->getBody()->getContents(), true, flags: \JSON_THROW_ON_ERROR); - $request->getBody()->rewind(); + $body = $this->getBody($request); if (!\is_array($body) || !isset($body['source']) || !\is_array($body['source'])) { throw new MalformedWebhookBodyException(); @@ -147,8 +144,7 @@ public function assemblePaymentPay(RequestInterface $request, ShopInterface $sho public function assemblePaymentFinalize(RequestInterface $request, ShopInterface $shop): PaymentFinalizeAction { - $body = \json_decode($request->getBody()->getContents(), true, flags: \JSON_THROW_ON_ERROR); - $request->getBody()->rewind(); + $body = $this->getBody($request); if (!\is_array($body) || !isset($body['source']) || !\is_array($body['source'])) { throw new MalformedWebhookBodyException(); @@ -166,8 +162,7 @@ public function assemblePaymentFinalize(RequestInterface $request, ShopInterface public function assemblePaymentCapture(RequestInterface $request, ShopInterface $shop): PaymentCaptureAction { - $body = \json_decode($request->getBody()->getContents(), true, flags: \JSON_THROW_ON_ERROR); - $request->getBody()->rewind(); + $body = $this->getBody($request); if (!\is_array($body) || !isset($body['source']) || !\is_array($body['source'])) { throw new MalformedWebhookBodyException(); @@ -185,8 +180,7 @@ public function assemblePaymentCapture(RequestInterface $request, ShopInterface public function assemblePaymentRecurringCapture(RequestInterface $request, ShopInterface $shop): PaymentRecurringAction { - $body = \json_decode($request->getBody()->getContents(), true, flags: \JSON_THROW_ON_ERROR); - $request->getBody()->rewind(); + $body = $this->getBody($request); if (!\is_array($body) || !isset($body['source']) || !\is_array($body['source'])) { throw new MalformedWebhookBodyException(); @@ -203,8 +197,7 @@ public function assemblePaymentRecurringCapture(RequestInterface $request, ShopI public function assemblePaymentValidate(RequestInterface $request, ShopInterface $shop): PaymentValidateAction { - $body = \json_decode($request->getBody()->getContents(), true, flags: \JSON_THROW_ON_ERROR); - $request->getBody()->rewind(); + $body = $this->getBody($request); if (!\is_array($body) || !isset($body['source']) || !\is_array($body['source'])) { throw new MalformedWebhookBodyException(); @@ -221,8 +214,7 @@ public function assemblePaymentValidate(RequestInterface $request, ShopInterface public function assemblePaymentRefund(RequestInterface $request, ShopInterface $shop): RefundAction { - $body = \json_decode($request->getBody()->getContents(), true, flags: \JSON_THROW_ON_ERROR); - $request->getBody()->rewind(); + $body = $this->getBody($request); if (!\is_array($body) || !isset($body['source']) || !\is_array($body['source'])) { throw new MalformedWebhookBodyException(); @@ -275,8 +267,7 @@ public function assembleStorefrontRequest(RequestInterface $request, ShopInterfa public function assembleCheckoutGatewayRequest(RequestInterface $request, ShopInterface $shop): CheckoutGatewayAction { - $body = \json_decode($request->getBody()->getContents(), true, flags: \JSON_THROW_ON_ERROR); - $request->getBody()->rewind(); + $body = $this->getBody($request); if (!\is_array($body) || !isset($body['source']) || !\is_array($body['source'])) { throw new MalformedWebhookBodyException(); @@ -294,8 +285,7 @@ public function assembleCheckoutGatewayRequest(RequestInterface $request, ShopIn public function assembleContextGatewayRequest(RequestInterface $request, ShopInterface $shop): ContextGatewayAction { - $body = \json_decode($request->getBody()->getContents(), true, flags: \JSON_THROW_ON_ERROR); - $request->getBody()->rewind(); + $body = $this->getBody($request); if (!\is_array($body) || !isset($body['source']) || !\is_array($body['source']) || !isset($body['data']) || !\is_array($body['data'])) { throw new MalformedWebhookBodyException(); @@ -312,8 +302,7 @@ public function assembleContextGatewayRequest(RequestInterface $request, ShopInt public function assembleInAppPurchasesFilterRequest(RequestInterface $request, ShopInterface $shop): FilterAction { - $body = \json_decode($request->getBody()->getContents(), true, flags: \JSON_THROW_ON_ERROR); - $request->getBody()->rewind(); + $body = $this->getBody($request); if (!\is_array($body) || !isset($body['source']) || !\is_array($body['source'])) { throw new MalformedWebhookBodyException(); @@ -330,6 +319,25 @@ public function assembleInAppPurchasesFilterRequest(RequestInterface $request, S ); } + /** + * @throws \JsonException + */ + private function getBody(RequestInterface $request): mixed + { + if ($request instanceof ServerRequestInterface) { + $body = $request->getParsedBody(); + + if ($body !== null) { + return $body; + } + } + + $body = \json_decode($request->getBody()->getContents(), true, flags: \JSON_THROW_ON_ERROR); + $request->getBody()->rewind(); + + return $body; + } + /** * @param array $source */ diff --git a/tests/Context/ContextResolverTest.php b/tests/Context/ContextResolverTest.php index ea749f7..c9798d0 100644 --- a/tests/Context/ContextResolverTest.php +++ b/tests/Context/ContextResolverTest.php @@ -9,6 +9,7 @@ use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\StreamInterface; use Shopware\App\SDK\Context\ContextResolver; use Shopware\App\SDK\Context\InAppPurchase\InAppPurchase; @@ -36,6 +37,17 @@ public function testAssembleWebhookMalformed(): void ); } + public function testAssembleWebhookUsesParsedBody(): void + { + $contextResolver = new ContextResolver($this->createMock(InAppPurchaseProvider::class)); + $request = $this->createMock(ServerRequestInterface::class); + $request->expects(static::once())->method('getParsedBody')->willReturn([]); + $request->expects(static::never())->method('getBody'); + + static::expectException(MalformedWebhookBodyException::class); + $contextResolver->assembleWebhook($request, $this->getShop()); + } + public function testAssembleWebhook(): void { $collection = new Collection([