<?php
declare(strict_types=1);
namespace PolPaymentPayolutionSW6\EventListener;
use PolPaymentPayolutionSW6\Component\CartHashGenerator\CartHashGeneratorInterface;
use PolPaymentPayolutionSW6\Component\CartProvider\CartProviderInterface;
use PolPaymentPayolutionSW6\Component\Configuration\ConfigurationServiceInterface;
use PolPaymentPayolutionSW6\Component\Validator\PaymentMethodValidator\PaymentMethodValidatorInterface;
use PolPaymentPayolutionSW6\Struct\CheckoutConfirmData;
use Shopware\Core\Checkout\Order\OrderEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\System\Language\LanguageEntity;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Page\Account\Order\AccountEditOrderPage;
use Shopware\Storefront\Page\Account\Order\AccountEditOrderPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPage;
use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
use Shopware\Storefront\Page\Page;
use Shopware\Storefront\Page\PageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CheckoutConfirmTemplateEventListener implements EventSubscriberInterface
{
private const FALLBACK_LOCALE = 'en';
private const ISO_NL = 'NL';
/**
* @var PaymentMethodValidatorInterface
*/
private $paymentMethodValidator;
/**
* @var CartProviderInterface
*/
private $cartProvider;
/**
* @var CartHashGeneratorInterface
*/
private $cartHashGenerator;
/**
* @var ConfigurationServiceInterface
*/
private $configurationService;
/**
* @var EntityRepositoryInterface
*/
private $languageRepository;
public function __construct(
PaymentMethodValidatorInterface $paymentMethodValidator,
CartProviderInterface $cartProvider,
CartHashGeneratorInterface $cartHashGenerator,
ConfigurationServiceInterface $configurationService,
EntityRepositoryInterface $languageRepository
) {
$this->paymentMethodValidator = $paymentMethodValidator;
$this->cartProvider = $cartProvider;
$this->cartHashGenerator = $cartHashGenerator;
$this->configurationService = $configurationService;
$this->languageRepository = $languageRepository;
}
public static function getSubscribedEvents(): array
{
return [
CheckoutConfirmPageLoadedEvent::class => 'addTemplateDataForPayment',
AccountEditOrderPageLoadedEvent::class => 'addTemplateDataForPayment',
];
}
public function addTemplateDataForPayment(PageLoadedEvent $event)
{
/** @var AccountEditOrderPage|CheckoutConfirmPage $page */
$page = $event->getPage();
$salesChannelContext = $event->getSalesChannelContext();
if (!$this->paymentMethodValidator->isPayolutionPaymentMethod($salesChannelContext->getPaymentMethod())) {
return;
}
if ($page->hasExtension(CheckoutConfirmData::EXTENSION_NAME)) {
$checkoutConfirmData = $page->getExtension(CheckoutConfirmData::EXTENSION_NAME);
} else {
$checkoutConfirmData = new CheckoutConfirmData();
}
$customFields = $salesChannelContext->getPaymentMethod()->getCustomFields();
$currentBirthday = $salesChannelContext->getCustomer()->getBirthday();
$currentBillingAddress = $salesChannelContext->getCustomer()->getActiveBillingAddress();
$existingOrder = $this->getOrderForCurrentPage($page);
$checkoutConfirmData->assign([
'template' => $customFields['payolution_template'] ?? null,
'mandateDocumentUrl' => CheckoutConfirmData::MANDATE_DOCUMENT_URL,
'privacyPolicyUrl' => $this->getPrivacyPolicyUrl($salesChannelContext),
'cartHash' => $this->getCartHashForCurrentPage($page, $salesChannelContext),
'orderId' => $existingOrder !== null ? $existingOrder->getId() : null,
'currentCompanyName' => $currentBillingAddress->getCompany(),
//'currentVatId' => $currentBillingAddress->getVatId(),
'currentPhoneNumber' => $currentBillingAddress->getPhoneNumber(),
'currentBirthDay' => $currentBirthday ? $currentBirthday->format('d') : null,
'currentBirthMonth' => $currentBirthday ? $currentBirthday->format('m') : null,
'currentBirthYear' => $currentBirthday ? $currentBirthday->format('Y') : null,
'invoiceShowPhoneNumber' => $currentBillingAddress->getCountry()->getIso() === static::ISO_NL,
]);
$page->addExtension(CheckoutConfirmData::EXTENSION_NAME, $checkoutConfirmData);
}
private function getCartHashForCurrentPage(Page $page, SalesChannelContext $salesChannelContext): string
{
/** @var AccountEditOrderPage|CheckoutConfirmPage $page */
$order = $this->getOrderForCurrentPage($page);
$cart = $this->cartProvider->getCartForCheckoutConfirmPage($page, $order, $salesChannelContext);
return $this->cartHashGenerator->generateCartHash($salesChannelContext, $cart);
}
private function getOrderForCurrentPage(Page $page): ?OrderEntity
{
/** @var AccountEditOrderPage|CheckoutConfirmPage $page */
if ($page instanceof AccountEditOrderPage) {
return $page->getOrder();
}
return null;
}
private function getPrivacyPolicyUrl(SalesChannelContext $salesChannelContext): string
{
$merchantId = $this->configurationService->getConfiguration(ConfigurationServiceInterface::MERCHANT_ID, $salesChannelContext->getSalesChannel()->getId());
$locale = $this->getLocale($salesChannelContext);
if (empty($merchantId)) {
return sprintf(str_replace('&mId=%s', '', CheckoutConfirmData::PRIVACY_POLICY_URL), $locale);
}
return sprintf(CheckoutConfirmData::PRIVACY_POLICY_URL, $locale, $merchantId);
}
private function getLocale(SalesChannelContext $salesChannelContext): string
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('id', $salesChannelContext->getSalesChannel()->getLanguageId()));
$criteria->addAssociation('locale');
$criteria->setLimit(1);
/** @var LanguageEntity $language */
$language = $this->languageRepository->search($criteria, $salesChannelContext->getContext())->first();
if ($language === null) {
return static::FALLBACK_LOCALE;
}
[$locale] = explode('-', $language->getLocale()->getCode());
if ($locale === null) {
return static::FALLBACK_LOCALE;
}
return strtolower($locale);
}
}