diff --git a/phpstan.neon b/phpstan.neon index 6b16c54b..46c6eae8 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -9,6 +9,11 @@ parameters: - '#generic class Shopware\\Core\\Framework\\Struct\\ArrayStruct does not specify its types#' - '#generic class Shopware\\Core\\Framework\\Struct\\ArrayStruct but does not specify its types#' + # ignored errors for backward compatibility (SW 6.5.3) + - '#Call to method getOrderTransactionId\(\) on an unknown class Shopware\\Core\\Checkout\\Payment\\Exception\\SyncPaymentProcessException#' + - '#Call to function method_exists\(\) with .*Shopware\\Core\\Framework\\Routing\\RoutingException.* and .* will always evaluate to false#' + - '#Call to method getOrderTransactionId\(\) on an unknown class Shopware\\Core\\Checkout\\Payment\\PaymentException#' + # NEXT-29041 - Shopware issue: https://github.com/shopware/shopware/blob/v6.6.0.0-rc2/phpstan.neon.dist#L221 - '#.* generic class Shopware\\Core\\Framework\\DataAbstractionLayer\\EntityRepository.*not specify its types: TEntityCollection#' - '#\(\) should return .*\|null but returns Shopware\\Core\\Framework\\DataAbstractionLayer\\Entity\|null#' diff --git a/src/Components/OrderManagement/Controller/ProductPanel.php b/src/Components/OrderManagement/Controller/ProductPanel.php index 920deaf5..9929ceff 100644 --- a/src/Components/OrderManagement/Controller/ProductPanel.php +++ b/src/Components/OrderManagement/Controller/ProductPanel.php @@ -25,10 +25,12 @@ use Ratepay\RpayPayments\Components\RatepayApi\Service\Request\PaymentDeliverService; use Ratepay\RpayPayments\Components\RatepayApi\Service\Request\PaymentReturnService; use Ratepay\RpayPayments\Util\CriteriaHelper; +use RuntimeException; use Shopware\Core\Checkout\Order\OrderEntity; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; +use Shopware\Core\Framework\Routing\Exception\InvalidRequestParameterException; use Shopware\Core\Framework\Routing\RoutingException; use Shopware\Core\Framework\Validation\DataValidationDefinition; use Shopware\Core\Framework\Validation\DataValidator; @@ -181,7 +183,15 @@ protected function processModify(Request $request, Context $context, string $ope if ($order instanceof OrderEntity) { $params = $request->request->all(); if (!isset($params['items']) || !is_array($params['items'])) { - throw RoutingException::invalidRequestParameter('items'); + if (class_exists(RoutingException::class) && method_exists(RoutingException::class, 'invalidRequestParameter')) { + throw RoutingException::invalidRequestParameter('items'); + } elseif (class_exists(InvalidRequestParameterException::class)) { + // required for shopware == 6.5.0.0 + throw new InvalidRequestParameterException('items'); + } + + // should never occur - just to be safe + throw new RuntimeException('Invalid request parameter: items'); } $items = []; diff --git a/src/Components/PaymentHandler/AbstractPaymentHandler.php b/src/Components/PaymentHandler/AbstractPaymentHandler.php index bf9d6e6f..7c19af0e 100644 --- a/src/Components/PaymentHandler/AbstractPaymentHandler.php +++ b/src/Components/PaymentHandler/AbstractPaymentHandler.php @@ -28,9 +28,11 @@ use Ratepay\RpayPayments\Components\RatepayApi\Service\Request\PaymentRequestService; use Ratepay\RpayPayments\Exception\RatepayException; use Ratepay\RpayPayments\Util\CriteriaHelper; +use RuntimeException; use Shopware\Core\Checkout\Order\OrderEntity; use Shopware\Core\Checkout\Payment\Cart\PaymentHandler\SynchronousPaymentHandlerInterface; use Shopware\Core\Checkout\Payment\Cart\SyncPaymentTransactionStruct; +use Shopware\Core\Checkout\Payment\Exception\SyncPaymentProcessException; use Shopware\Core\Checkout\Payment\PaymentException; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\Entity; @@ -42,6 +44,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Session\Session; +use Throwable; abstract class AbstractPaymentHandler implements SynchronousPaymentHandlerInterface { @@ -71,10 +74,7 @@ public function pay(SyncPaymentTransactionStruct $transaction, RequestDataBag $d $order = $this->getOrderWithAssociations($transaction->getOrder(), $salesChannelContext->getContext()); if (!$order instanceof OrderEntity || $ratepayData->count() === 0) { - throw PaymentException::syncProcessInterrupted( - $transaction->getOrderTransaction()->getId(), - 'unknown error during payment' - ); + throw $this->syncProcessInterrupted($transaction->getOrderTransaction()->getId(), 'unknown error during payment'); } try { @@ -137,11 +137,7 @@ public function pay(SyncPaymentTransactionStruct $transaction, RequestDataBag $d $session->getFlashBag()->add(StorefrontController::DANGER, $ratepayException->getMessage()); } - throw PaymentException::syncProcessInterrupted( - $transaction->getOrderTransaction()->getId(), - $ratepayException->getMessage(), - $ratepayException - ); + throw $this->syncProcessInterrupted($transaction->getOrderTransaction()->getId(), $ratepayException->getMessage(), $ratepayException); } } @@ -187,4 +183,17 @@ protected function getOrderWithAssociations(OrderEntity $order, Context $context { return $this->orderRepository->search(CriteriaHelper::getCriteriaForOrder($order->getId()), $context)->first(); } + + private function syncProcessInterrupted(string $orderTransactionId, string $errorMessage, ?Throwable $e = null): Throwable + { + if (class_exists(PaymentException::class)) { + return PaymentException::syncProcessInterrupted($orderTransactionId, $errorMessage, $e); + } elseif (class_exists(SyncPaymentProcessException::class)) { + // required for shopware version <= 6.5.3 + return new SyncPaymentProcessException($orderTransactionId, $errorMessage, $e); // @phpstan-ignore-line + } + + // should never occur - just to be safe + return new RuntimeException('payment interrupted: ' . $errorMessage, 0, $e); + } } diff --git a/src/Components/RedirectException/Subscriber/RedirectExceptionListener.php b/src/Components/RedirectException/Subscriber/RedirectExceptionListener.php index 0b3cf9bb..08afac28 100644 --- a/src/Components/RedirectException/Subscriber/RedirectExceptionListener.php +++ b/src/Components/RedirectException/Subscriber/RedirectExceptionListener.php @@ -14,6 +14,7 @@ use Ratepay\RpayPayments\Components\RedirectException\Exception\ForwardException; use Ratepay\RpayPayments\Components\RedirectException\Exception\RedirectException; use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStateHandler; +use Shopware\Core\Checkout\Payment\Exception\SyncPaymentProcessException; use Shopware\Core\Checkout\Payment\PaymentException; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\Routing\RequestTransformerInterface; @@ -47,7 +48,10 @@ public function onKernelException(ExceptionEvent $event): void $throwable = $event->getThrowable(); $prevThrowable = $throwable->getPrevious(); - if ($prevThrowable instanceof PaymentException) { + if ((class_exists(PaymentException::class) && $prevThrowable instanceof PaymentException) + || (class_exists(SyncPaymentProcessException::class) && $prevThrowable instanceof SyncPaymentProcessException) + ) { + // SyncPaymentProcessException and class_exists checks are required for sw <= 6.5.3 compatibility // set the transaction to failed. Without this, the customer will not be able to try a repayment. $this->orderTransactionStateHandler->fail($prevThrowable->getOrderTransactionId(), Context::createDefaultContext()); }