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

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 */
  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.     public function onSystemConfigWritten(EntityWrittenEvent $event)
  39.     {
  40.         foreach ($event->getPayloads() as $payload) {
  41.             $this->checkSystemConfigChange(
  42.                 (string)$payload['configurationKey'],
  43.                 $payload['configurationValue'],
  44.                 $payload['salesChannelId'],
  45.                 $event->getContext()
  46.             );
  47.         }
  48.     }
  49.     /**
  50.      * @param string $key
  51.      * @param $value
  52.      * @param string|null $salesChannelId
  53.      * @param Context $context
  54.      */
  55.     private function checkSystemConfigChange(string $key$value, ?string $salesChannelIdContext $context)
  56.     {
  57.         if (in_array($key, [
  58.             SettingsService::SYSTEM_CONFIG_DOMAIN SettingsService::LIVE_PROFILE_ID,
  59.             SettingsService::SYSTEM_CONFIG_DOMAIN SettingsService::TEST_PROFILE_ID,
  60.         ])) {
  61.             $this->fixProfileIdAfterChange(
  62.                 $key,
  63.                 $value,
  64.                 $salesChannelId,
  65.                 strpos($keySettingsService::TEST_PROFILE_ID) !== false,
  66.                 $context
  67.             );
  68.         }
  69.         if (in_array($key, [
  70.             SettingsService::SYSTEM_CONFIG_DOMAIN SettingsService::LIVE_API_KEY,
  71.             SettingsService::SYSTEM_CONFIG_DOMAIN SettingsService::TEST_API_KEY,
  72.         ])) {
  73.             $this->fetchProfileIdForApiKey(
  74.                 $value,
  75.                 $salesChannelId,
  76.                 strpos($keySettingsService::TEST_API_KEY) !== false,
  77.                 $context
  78.             );
  79.         }
  80.     }
  81.     /**
  82.      * @param $value
  83.      * @param string|null $salesChannelId
  84.      * @param bool $testMode
  85.      * @param Context $context
  86.      */
  87.     private function fetchProfileIdForApiKey($value, ?string $salesChannelIdbool $testModeContext $context)
  88.     {
  89.         $profileKey SettingsService::SYSTEM_CONFIG_DOMAIN .
  90.             ($testMode ?
  91.                 SettingsService::TEST_PROFILE_ID :
  92.                 SettingsService::LIVE_PROFILE_ID);
  93.         if (empty($value)) {
  94.             // If this api key has been "deleted", also remove the profile ID.
  95.             $this->logger->debug(
  96.                 "API key has been removed, removing associated profile ID",
  97.                 [
  98.                     'salesChannelId' => $salesChannelId ?? 'null',
  99.                     'mode' => $testMode 'test' 'live',
  100.                 ]
  101.             );
  102.             $this->settingsService->setProfileId(null$salesChannelId$testMode);
  103.             return;
  104.         }
  105.         $this->logger->debug(
  106.             "Fetching profile ID",
  107.             [
  108.                 'salesChannelId' => $salesChannelId ?? 'null',
  109.                 'mode' => $testMode 'test' 'live',
  110.             ]
  111.         );
  112.         $this->apiClient->setApiKey($value);
  113.         $profile ProfileHelper::getProfile($this->apiClient, new MollieSettingStruct());
  114.         if(!$profile instanceof Profile) {
  115.             $this->logger->error(
  116.                 'Could not get profile using these settings',
  117.                 [
  118.                     'salesChannelId' => $salesChannelId ?? 'null',
  119.                     'mode' => $testMode 'test' 'live',
  120.                 ]
  121.             );
  122.             return;
  123.         }
  124.         $this->profileIdStorage[$salesChannelId $profileKey] = $profile->id;
  125.         $this->logger->debug(
  126.             "Saving profile ID",
  127.             [
  128.                 'salesChannelId' => $salesChannelId ?? 'null',
  129.                 'mode' => $testMode 'test' 'live',
  130.                 'profileId' => $profile->id
  131.             ]
  132.         );
  133.         $this->settingsService->setProfileId($profile->id$salesChannelId$testMode);
  134.     }
  135.     /**
  136.      * Why do we need to fix the profile ID?
  137.      * When adding a key to the system config programmatically, even if there is no field for it in config.xml,
  138.      * when saving the configuration in the administration, Shopware will also save those keys.
  139.      * We need to fix the profile ID, because we fetch the new profile ID from Mollie and save it to the system config,
  140.      * and then Shopware overwrites it with the old one afterwards.
  141.      *
  142.      * @param string $key
  143.      * @param $value
  144.      * @param string|null $salesChannelId
  145.      * @param bool $testMode
  146.      * @param Context $context
  147.      */
  148.     private function fixProfileIdAfterChange(string $key$value, ?string $salesChannelIdbool $testModeContext $context)
  149.     {
  150.         if (isset($this->profileIdStorage[$salesChannelId $key])) {
  151.             // If the old $value is the same as the new profile ID in storage, then dont set it again
  152.             // Will end up in an endless loop otherwise.
  153.             if ($this->profileIdStorage[$salesChannelId $key] === $value) {
  154.                 return;
  155.             }
  156.             $this->logger->debug(
  157.                 "A new profile ID was fetched, but the admin saved the old one again, correcting mistake.",
  158.                 [
  159.                     'salesChannelId' => $salesChannelId ?? 'null',
  160.                     'mode' => $testMode 'test' 'live',
  161.                     'profileId' => $value
  162.                 ]
  163.             );
  164.             $this->settingsService->setProfileId($this->profileIdStorage[$salesChannelId $key], $salesChannelId$testMode);
  165.         } else {
  166.             // If we haven't stored the profile ID from Mollie, but we are getting a value here from the admin,
  167.             // then we no longer need to store this key, so delete it.
  168.             if ($value) {
  169.                 $this->logger->debug(
  170.                     "Removing profile ID",
  171.                     [
  172.                         'salesChannelId' => $salesChannelId ?? 'null',
  173.                         'mode' => $testMode 'test' 'live',
  174.                     ]
  175.                 );
  176.                 $this->settingsService->setProfileId(null$salesChannelId$testMode);
  177.             }
  178.         }
  179.     }
  180. }