custom/plugins/MolliePayments/src/Subscriber/SystemConfigSubscriber.php line 53

Open in your IDE?
  1. <?php
  2. namespace Kiener\MolliePayments\Subscriber;
  3. use Kiener\MolliePayments\Helper\ProfileHelper;
  4. use Kiener\MolliePayments\Service\SettingsService;
  5. use Kiener\MolliePayments\Setting\MollieSettingStruct;
  6. use Mollie\Api\MollieApiClient;
  7. use Mollie\Api\Resources\Profile;
  8. use Psr\Log\LoggerInterface;
  9. use Shopware\Core\Framework\Context;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
  11. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  12. class SystemConfigSubscriber implements EventSubscriberInterface
  13. {
  14.     /** @var SettingsService */
  15.     private $settingsService;
  16.     /** @var LoggerInterface */
  17.     private $logger;
  18.     /** @var MollieApiClient */
  19.     private $apiClient;
  20.     /** @var array<mixed> */
  21.     private $profileIdStorage = [];
  22.     /**
  23.      * @param SettingsService $settingsService
  24.      * @param LoggerInterface $logger
  25.      */
  26.     public function __construct(SettingsService $settingsServiceLoggerInterface $logger)
  27.     {
  28.         $this->settingsService $settingsService;
  29.         $this->logger $logger;
  30.         $this->apiClient = new MollieApiClient();
  31.     }
  32.     public static function getSubscribedEvents()
  33.     {
  34.         return [
  35.             'system_config.written' => 'onSystemConfigWritten',
  36.         ];
  37.     }
  38.     /**
  39.      * @param EntityWrittenEvent $event
  40.      */
  41.     public function onSystemConfigWritten(EntityWrittenEvent $event): void
  42.     {
  43.         foreach ($event->getPayloads() as $payload) {
  44.             $this->checkSystemConfigChange(
  45.                 (string)$payload['configurationKey'],
  46.                 $payload['configurationValue'],
  47.                 $payload['salesChannelId'] ?? null,
  48.                 $event->getContext()
  49.             );
  50.         }
  51.     }
  52.     /**
  53.      * @param string $key
  54.      * @param mixed $value
  55.      * @param null|string $salesChannelId
  56.      * @param Context $context
  57.      */
  58.     private function checkSystemConfigChange(string $key$value, ?string $salesChannelIdContext $context): void
  59.     {
  60.         if (in_array($key, [
  61.             SettingsService::SYSTEM_CONFIG_DOMAIN SettingsService::LIVE_PROFILE_ID,
  62.             SettingsService::SYSTEM_CONFIG_DOMAIN SettingsService::TEST_PROFILE_ID,
  63.         ])) {
  64.             $this->fixProfileIdAfterChange(
  65.                 $key,
  66.                 $value,
  67.                 $salesChannelId,
  68.                 strpos($keySettingsService::TEST_PROFILE_ID) !== false,
  69.                 $context
  70.             );
  71.         }
  72.         if (in_array($key, [
  73.             SettingsService::SYSTEM_CONFIG_DOMAIN SettingsService::LIVE_API_KEY,
  74.             SettingsService::SYSTEM_CONFIG_DOMAIN SettingsService::TEST_API_KEY,
  75.         ])) {
  76.             $this->fetchProfileIdForApiKey(
  77.                 $value,
  78.                 $salesChannelId,
  79.                 strpos($keySettingsService::TEST_API_KEY) !== false,
  80.                 $context
  81.             );
  82.         }
  83.     }
  84.     /**
  85.      * @param mixed $value
  86.      * @param null|string $salesChannelId
  87.      * @param bool $testMode
  88.      * @param Context $context
  89.      * @throws \Mollie\Api\Exceptions\ApiException
  90.      */
  91.     private function fetchProfileIdForApiKey($value, ?string $salesChannelIdbool $testModeContext $context): void
  92.     {
  93.         $profileKey SettingsService::SYSTEM_CONFIG_DOMAIN .
  94.             ($testMode ?
  95.                 SettingsService::TEST_PROFILE_ID :
  96.                 SettingsService::LIVE_PROFILE_ID);
  97.         if (empty($value)) {
  98.             // If this api key has been "deleted", also remove the profile ID.
  99.             $this->logger->debug(
  100.                 "API key has been removed, removing associated profile ID",
  101.                 [
  102.                     'salesChannelId' => $salesChannelId ?? 'null',
  103.                     'mode' => $testMode 'test' 'live',
  104.                 ]
  105.             );
  106.             $this->settingsService->setProfileId(null$salesChannelId$testMode);
  107.             return;
  108.         }
  109.         $this->logger->debug(
  110.             "Fetching profile ID",
  111.             [
  112.                 'salesChannelId' => $salesChannelId ?? 'null',
  113.                 'mode' => $testMode 'test' 'live',
  114.             ]
  115.         );
  116.         $this->apiClient->setApiKey($value);
  117.         $profile ProfileHelper::getProfile($this->apiClient, new MollieSettingStruct());
  118.         if (!$profile instanceof Profile) {
  119.             $this->logger->error(
  120.                 'Could not get profile using these settings',
  121.                 [
  122.                     'salesChannelId' => $salesChannelId ?? 'null',
  123.                     'mode' => $testMode 'test' 'live',
  124.                 ]
  125.             );
  126.             return;
  127.         }
  128.         $this->profileIdStorage[$salesChannelId $profileKey] = $profile->id;
  129.         $this->logger->debug(
  130.             "Saving profile ID",
  131.             [
  132.                 'salesChannelId' => $salesChannelId ?? 'null',
  133.                 'mode' => $testMode 'test' 'live',
  134.                 'profileId' => $profile->id
  135.             ]
  136.         );
  137.         $this->settingsService->setProfileId($profile->id$salesChannelId$testMode);
  138.     }
  139.     /**
  140.      * Why do we need to fix the profile ID?
  141.      * When adding a key to the system config programmatically, even if there is no field for it in config.xml,
  142.      * when saving the configuration in the administration, Shopware will also save those keys.
  143.      * We need to fix the profile ID, because we fetch the new profile ID from Mollie and save it to the system config,
  144.      * and then Shopware overwrites it with the old one afterwards.
  145.      *
  146.      * @param string $key
  147.      * @param mixed $value
  148.      * @param null|string $salesChannelId
  149.      * @param bool $testMode
  150.      * @param Context $context
  151.      */
  152.     private function fixProfileIdAfterChange(string $key$value, ?string $salesChannelIdbool $testModeContext $context): void
  153.     {
  154.         if (isset($this->profileIdStorage[$salesChannelId $key])) {
  155.             // If the old $value is the same as the new profile ID in storage, then dont set it again
  156.             // Will end up in an endless loop otherwise.
  157.             if ($this->profileIdStorage[$salesChannelId $key] === $value) {
  158.                 return;
  159.             }
  160.             $this->logger->debug(
  161.                 "A new profile ID was fetched, but the admin saved the old one again, correcting mistake.",
  162.                 [
  163.                     'salesChannelId' => $salesChannelId ?? 'null',
  164.                     'mode' => $testMode 'test' 'live',
  165.                     'profileId' => $value
  166.                 ]
  167.             );
  168.             $this->settingsService->setProfileId($this->profileIdStorage[$salesChannelId $key], $salesChannelId$testMode);
  169.         } else {
  170.             // If we haven't stored the profile ID from Mollie, but we are getting a value here from the admin,
  171.             // then we no longer need to store this key, so delete it.
  172.             if ($value) {
  173.                 $this->logger->debug(
  174.                     "Removing profile ID",
  175.                     [
  176.                         'salesChannelId' => $salesChannelId ?? 'null',
  177.                         'mode' => $testMode 'test' 'live',
  178.                     ]
  179.                 );
  180.                 $this->settingsService->setProfileId(null$salesChannelId$testMode);
  181.             }
  182.         }
  183.     }
  184. }