custom/plugins/WizmoGmbhIvyPayment/src/Subscriber/ConfigSubscriber.php line 76

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace WizmoGmbh\IvyPayment\Subscriber;
  4. use Doctrine\DBAL\Connection;
  5. use Doctrine\DBAL\Exception;
  6. use Shopware\Core\Defaults;
  7. use Shopware\Core\Framework\Uuid\Uuid;
  8. use Shopware\Core\System\SalesChannel\Context\AbstractSalesChannelContextFactory;
  9. use Shopware\Storefront\Framework\Routing\Router;
  10. use Shopware\Storefront\Framework\Twig\TemplateConfigAccessor;
  11. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  12. use Symfony\Component\HttpFoundation\JsonResponse;
  13. use Symfony\Component\HttpKernel\Event\ResponseEvent;
  14. use Symfony\Component\HttpKernel\KernelEvents;
  15. use Symfony\Component\Routing\RouterInterface;
  16. use WizmoGmbh\IvyPayment\Components\Config\ConfigHandler;
  17. use WizmoGmbh\IvyPayment\Exception\IvyApiException;
  18. use WizmoGmbh\IvyPayment\IvyApi\ApiClient;
  19. use Symfony\Component\HttpFoundation\Response;
  20. class ConfigSubscriber implements EventSubscriberInterface
  21. {
  22.     private ConfigHandler $configHandler;
  23.     private RouterInterface $router;
  24.     private ApiClient $ivyApiClient;
  25.     private TemplateConfigAccessor $templateConfigAccessor;
  26.     private AbstractSalesChannelContextFactory $salesChannelContextFactory;
  27.     private Connection $connection;
  28.     /**
  29.      * @param ConfigHandler $configHandler
  30.      * @param RouterInterface $router
  31.      * @param ApiClient $ivyApiClient
  32.      * @param TemplateConfigAccessor $templateConfigAccessor
  33.      * @param AbstractSalesChannelContextFactory $salesChannelContextFactory
  34.      * @param Connection $connection
  35.      */
  36.     public function __construct(
  37.         ConfigHandler $configHandler,
  38.         RouterInterface $router,
  39.         ApiClient $ivyApiClient,
  40.         TemplateConfigAccessor $templateConfigAccessor,
  41.         AbstractSalesChannelContextFactory $salesChannelContextFactory,
  42.         Connection $connection
  43.     )
  44.     {
  45.         $this->configHandler $configHandler;
  46.         $this->router $router;
  47.         $this->ivyApiClient $ivyApiClient;
  48.         $this->templateConfigAccessor $templateConfigAccessor;
  49.         $this->salesChannelContextFactory $salesChannelContextFactory;
  50.         $this->connection $connection;
  51.     }
  52.     public static function getSubscribedEvents(): array
  53.     {
  54.         return [
  55.             // Ensure event is executed before "Shopware\Core\System\SalesChannel\Api\StoreApiResponseListener".
  56.             KernelEvents::RESPONSE => ['onResponse'11000],
  57.         ];
  58.     }
  59.     /**
  60.      * @param ResponseEvent $event
  61.      * @return void
  62.      * @throws \Exception
  63.      */
  64.     public function onResponse(ResponseEvent $event): void
  65.     {
  66.         $request $event->getRequest();
  67.         if ($request->attributes->get('_route') !== 'api.action.core.save.system-config.batch') {
  68.             return;
  69.         }
  70.         foreach ($request->request->all() as $salesChannelId => $kvs) {
  71.             if ($salesChannelId === 'null') {
  72.                 $salesChannelId null;
  73.             }
  74.             $errors = [];
  75.             if (isset ($kvs['WizmoGmbhIvyPayment.config.ProductionIvyApiKey']) && (string)$kvs['WizmoGmbhIvyPayment.config.ProductionIvyApiKey'] !== '') {
  76.                 try {
  77.                     $this->updateMerchant($salesChannelIdfalse);
  78.                 } catch (\Exception $e) {
  79.                     $errors[] = $e->getMessage();
  80.                 }
  81.             }
  82.             if (isset ($kvs['WizmoGmbhIvyPayment.config.SandboxIvyApiKey']) && (string)$kvs['WizmoGmbhIvyPayment.config.SandboxIvyApiKey'] !== '') {
  83.                 try {
  84.                     $this->updateMerchant($salesChannelIdtrue);
  85.                 } catch (\Exception $e) {
  86.                     $errors[] = $e->getMessage();
  87.                 }
  88.             }
  89.             if (!empty($errors)) {
  90.                 $event->setResponse(new JsonResponse([
  91.                     'errors' => \implode('; '$errors),
  92.                 ], Response::HTTP_BAD_REQUEST));
  93.             }
  94.         }
  95.     }
  96.     /**
  97.      * @param string|null $salesChannelId
  98.      * @param bool $isSandBox
  99.      * @return void
  100.      * @throws Exception
  101.      * @throws IvyApiException
  102.      */
  103.     private function updateMerchant(?string $salesChannelIdbool $isSandBox): void
  104.     {
  105.         $config $this->configHandler->getFullConfigBySalesChannelId($salesChannelId$isSandBoxtrue);
  106.         $quoteCallbackUrl $this->router->generate('frontend.ivyexpress.callback', [], Router::ABSOLUTE_URL);
  107.         $successCallbackUrl $this->router->generate('frontend.ivypayment.finalize.transaction', [], Router::ABSOLUTE_URL);
  108.         $errorCallbackUrl $this->router->generate('frontend.ivypayment.failed.transaction', [], Router::ABSOLUTE_URL);
  109.         $webhookUrl $this->router->generate('ivypayment.update.transaction', [], Router::ABSOLUTE_URL);
  110.         $privacyUrl $this->router->generate('frontend.cms.page', ['id' => $config['privacyPage']], Router::ABSOLUTE_URL);
  111.         $tosUrl $this->router->generate('frontend.cms.page', ['id' => $config['tosPage']], Router::ABSOLUTE_URL);
  112.         $completeCallbackUrl $this->router->generate('frontend.ivyexpress.confirm', [], Router::ABSOLUTE_URL);
  113.         if (!$salesChannelId) {
  114.             $salesChannelId $this->connection->createQueryBuilder()
  115.                 ->select('LOWER(HEX(s.id))')
  116.                 ->from('sales_channel''s')
  117.                 ->where('s.active = 1')
  118.                 ->andWhere('s.type_id = UNHEX(:salesChannelType)')
  119.                 ->setParameter('salesChannelType'Defaults::SALES_CHANNEL_TYPE_STOREFRONT)
  120.                 ->execute()
  121.                 ->fetchOne();
  122.         }
  123.         $salesChannelContext $this->salesChannelContextFactory->create(Uuid::randomHex(), $salesChannelId, []);
  124.         $themeId $this->connection->createQueryBuilder()
  125.             ->select('LOWER(HEX(t.theme_id))')
  126.             ->from('theme_sales_channel''t')
  127.             ->where('t.sales_channel_id = UNHEX(:salesChannelId)')
  128.             ->setParameter('salesChannelId'$salesChannelId)
  129.             ->execute()
  130.             ->fetchOne();
  131.         $logoUrl $this->templateConfigAccessor->theme('sw-logo-tablet'$salesChannelContext$themeId);
  132.         $jsonContent \json_encode([
  133.             'quoteCallbackUrl' => $quoteCallbackUrl,
  134.             'successCallbackUrl' => $successCallbackUrl,
  135.             'errorCallbackUrl' => $errorCallbackUrl,
  136.             'completeCallbackUrl' => $completeCallbackUrl,
  137.             'webhookUrl' => $webhookUrl,
  138.             'privacyUrl' => $privacyUrl,
  139.             'tosUrl' => $tosUrl,
  140.             'shopLogo' => $logoUrl,
  141.         ]);
  142.         $this->ivyApiClient->sendApiRequest('merchant/update'$config$jsonContent);
  143.     }
  144. }