<?php declare(strict_types=1);
namespace VRPayment\VRPay;
use \Generator;
use Shopware\Core\Checkout\Payment\DataAbstractionLayer\PaymentMethodRepositoryDecorator;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\Plugin;
use Shopware\Core\Framework\Plugin\Context\InstallContext;
use Shopware\Core\Framework\Plugin\Context\UninstallContext;
use Shopware\Core\Framework\Plugin\Context\ActivateContext;
use Shopware\Core\Framework\Plugin\Context\DeactivateContext;
/**
* Class VRPay
* Main plugin class, takes care of (un)installing routines
*
* @package VRPayment\VRPay
*/
class VRPay extends Plugin
{
private static $paymentHandlers = [
'GiroPay',
'Paypal',
'Paydirekt',
'CreditCard',
'DirectDebit',
'KlarnaSofort',
'EasyCredit',
];
/*
* plugin lifecycle methods
*/
public function install(InstallContext $installContext): void
{
parent::install($installContext);
$this->createPaymentMethods($installContext->getContext());
}
public function uninstall(UninstallContext $uninstallContext): void
{
$this->updatePaymentMethodsActiveState(false, $uninstallContext->getContext());
parent::uninstall($uninstallContext);
}
public function activate(ActivateContext $activateContext): void
{
parent::activate($activateContext);
$this->updatePaymentMethodsActiveState(true, $activateContext->getContext());
}
public function deactivate(DeactivateContext $deactivateContext): void
{
$this->updatePaymentMethodsActiveState(false, $deactivateContext->getContext());
parent::deactivate($deactivateContext);
}
/*
* helpers to create and update payment methods
*/
/**
* Creates a payment method for every payment method this plugin provides
*
* @param Context $context
*/
private function createPaymentMethods(Context $context)
{
/** @var Plugin\Util\PluginIdProvider $pluginIdProvider */
$pluginIdProvider = $this->container->get(Plugin\Util\PluginIdProvider::class);
$pluginId = $pluginIdProvider->getPluginIdByBaseClass(get_class($this), $context);
$methodsToCreate = [];
foreach($this->enumeratePaymentHandlers() as $paymentHandler)
{
if($this->getPaymentMethodId($paymentHandler))
{
continue;
}
$methodsToCreate[] = [
'handlerIdentifier' => $paymentHandler,
'name' => $paymentHandler::getLabel(),
'description' => $paymentHandler::getDescription(),
'pluginId' => $pluginId,
];
}
if(!empty($methodsToCreate))
{
/** @var EntityRepositoryInterface $paymentRepository */
/** @var PaymentMethodRepositoryDecorator $paymentRepository */
$paymentRepository = $this->container->get('payment_method.repository');
$paymentRepository->create($methodsToCreate, $context);
}
}
/**
* Lists all class names of payment handlers this plugin provides
*
* @return string[]|Generator
*/
public function enumeratePaymentHandlers(): Generator
{
foreach(self::$paymentHandlers as $handler)
{
yield sprintf('VRPayment\VRPay\Service\Payment\%s', $handler);
}
}
/**
* Finds the id of a payment method based on the current plugin id and the given payment handler class
*
* @param string $paymentHandler the class name of the payment handler to find the payment method for
*
* @return string|null the id of the according payment method or null if none can be found
*
* @throws \Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException
*/
private function getPaymentMethodId(string $paymentHandler): ?string
{
/** @var EntityRepositoryInterface $paymentRepository */
$paymentRepository = $this->container->get('payment_method.repository');
$paymentCriteria = (new Criteria())->addFilter(new EqualsFilter('handlerIdentifier', $paymentHandler));
$paymentIds = $paymentRepository->searchIds($paymentCriteria, Context::createDefaultContext());
if($paymentIds->getTotal() === 0)
{
return null;
}
return $paymentIds->getIds()[0];
}
/**
* Updates the active state of all payment methods this plugin provides
*
* @param bool $activeState the active state to set
*
* @param Context $context
*
* @throws \Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException
*/
private function updatePaymentMethodsActiveState(bool $activeState, Context $context)
{
$updates = [];
foreach($this->enumeratePaymentHandlers() as $paymentHandler)
{
$paymentMethodId = $this->getPaymentMethodId($paymentHandler);
if(!$paymentMethodId)
{
continue;
}
$updates[] = [
'id' => $paymentMethodId,
'active' => $activeState,
];
}
if(!empty($updates))
{
/** @var EntityRepositoryInterface $paymentRepository */
$paymentRepository = $this->container->get('payment_method.repository');
$paymentRepository->update($updates, $context);
}
}
}