<?php declare(strict_types=1);
namespace Shopware\Core\Checkout\Payment\DataAbstractionLayer;
use Shopware\Core\Checkout\Payment\Cart\PaymentHandler\AsynchronousPaymentHandlerInterface;
use Shopware\Core\Checkout\Payment\Cart\PaymentHandler\PreparedPaymentHandlerInterface;
use Shopware\Core\Checkout\Payment\Cart\PaymentHandler\RefundPaymentHandlerInterface;
use Shopware\Core\Checkout\Payment\Cart\PaymentHandler\SynchronousPaymentHandlerInterface;
use Shopware\Core\Checkout\Payment\PaymentEvents;
use Shopware\Core\Checkout\Payment\PaymentMethodEntity;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
class PaymentHandlerIdentifierSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
PaymentEvents::PAYMENT_METHOD_LOADED_EVENT => 'formatHandlerIdentifier',
];
}
public function formatHandlerIdentifier(EntityLoadedEvent $event): void
{
/** @var PaymentMethodEntity $entity */
foreach ($event->getEntities() as $entity) {
$this->setPaymentMethodHandlerRuntimeFields($entity);
$explodedHandlerIdentifier = explode('\\', $entity->getHandlerIdentifier());
$last = $explodedHandlerIdentifier[\count($explodedHandlerIdentifier) - 1];
$entity->setShortName((new CamelCaseToSnakeCaseNameConverter())->normalize($last));
if (\count($explodedHandlerIdentifier) < 2) {
$entity->setFormattedHandlerIdentifier($entity->getHandlerIdentifier());
continue;
}
/** @var string|null $firstHandlerIdentifier */
$firstHandlerIdentifier = array_shift($explodedHandlerIdentifier);
$lastHandlerIdentifier = array_pop($explodedHandlerIdentifier);
if ($firstHandlerIdentifier === null || $lastHandlerIdentifier === null) {
continue;
}
$formattedHandlerIdentifier = 'handler_'
. mb_strtolower($firstHandlerIdentifier)
. '_'
. mb_strtolower($lastHandlerIdentifier);
$entity->setFormattedHandlerIdentifier($formattedHandlerIdentifier);
}
}
private function setPaymentMethodHandlerRuntimeFields(PaymentMethodEntity $paymentMethod): void
{
if ($paymentMethod->getAppPaymentMethod()) {
$this->setFieldsByAppPaymentMethod($paymentMethod);
return;
}
$handlerIdentifier = $paymentMethod->getHandlerIdentifier();
if (\is_a($handlerIdentifier, SynchronousPaymentHandlerInterface::class, true)) {
$paymentMethod->setSynchronous(true);
}
if (\is_a($handlerIdentifier, AsynchronousPaymentHandlerInterface::class, true)) {
$paymentMethod->setAsynchronous(true);
}
if (\is_a($handlerIdentifier, PreparedPaymentHandlerInterface::class, true)) {
$paymentMethod->setPrepared(true);
}
if (\is_a($handlerIdentifier, RefundPaymentHandlerInterface::class, true)) {
$paymentMethod->setRefundable(true);
}
}
private function setFieldsByAppPaymentMethod(PaymentMethodEntity $paymentMethod): void
{
if (!$paymentMethod->getAppPaymentMethod()) {
return;
}
$appPaymentMethod = $paymentMethod->getAppPaymentMethod();
if ($appPaymentMethod->getRefundUrl()) {
$paymentMethod->setRefundable(true);
}
if ($appPaymentMethod->getValidateUrl() && $appPaymentMethod->getCaptureUrl()) {
$paymentMethod->setPrepared(true);
}
if ($appPaymentMethod->getPayUrl() && $appPaymentMethod->getFinalizeUrl()) {
$paymentMethod->setAsynchronous(true);
}
if ($paymentMethod->isAsynchronous()) {
$paymentMethod->setSynchronous(true);
}
}
}