custom/plugins/NewsletterSendinblue/src/NewsletterSendinblue.php line 28

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace NewsletterSendinblue;
  3. use Doctrine\DBAL\Connection;
  4. use Exception;
  5. use Monolog\Logger;
  6. use NewsletterSendinblue\Core\Content\Cart\AbandonedCartDefinition;
  7. use NewsletterSendinblue\Service\ApiClientService;
  8. use NewsletterSendinblue\Service\ConfigService;
  9. use NewsletterSendinblue\Service\IntegrationService;
  10. use NewsletterSendinblue\Service\VersionProvider;
  11. use Shopware\Core\Framework\Context;
  12. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  14. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\ContainsFilter;
  16. use Shopware\Core\Framework\Plugin;
  17. use Shopware\Core\Framework\Plugin\Context\DeactivateContext;
  18. use Shopware\Core\Framework\Plugin\Context\InstallContext;
  19. use Shopware\Core\Framework\Plugin\Context\UninstallContext;
  20. use Shopware\Core\Framework\Plugin\Context\UpdateContext;
  21. use Shopware\Core\Framework\Uuid\Uuid;
  22. use Shopware\Core\System\SystemConfig\SystemConfigEntity;
  23. use Shopware\Core\System\SystemConfig\SystemConfigService;
  24. use Symfony\Component\DependencyInjection\ContainerBuilder;
  25. class NewsletterSendinblue extends Plugin
  26. {
  27.     public const ACL_ROLE_NAME 'Brevo';
  28.     public const OLD_ACL_ROLE_NAME 'Sendinblue';
  29.     public const INTEGRATION_LABEL 'Brevo';
  30.     public const OLD_INTEGRATION_LABEL 'Sendinblue';
  31.     public const PLUGIN_LABEL 'Sendinblue';
  32.     public const USER_CONNECTION_ID_CUSTOM_FIELD 'newsletter_sendinblue_user_connection_id';
  33.     public const CUSTOM_TABLES = [
  34.         AbandonedCartDefinition::ENTITY_NAME
  35.     ];
  36.     /**
  37.      * @var IntegrationService
  38.      */
  39.     private $integrationService;
  40.     /**
  41.      * @param ContainerBuilder $container
  42.      */
  43.     public function build(ContainerBuilder $container): void
  44.     {
  45.         parent::build($container);
  46.         $container->setParameter('sendinblue.service_worker_path'$this->getPath() . '/Resources/js/service-worker.js');
  47.     }
  48.     /**
  49.      * @param InstallContext $installContext
  50.      */
  51.     public function postInstall(InstallContext $installContext): void
  52.     {
  53.         $this->createAclRole($installContext->getContext());
  54.         $this->createIntegrations($installContext->getContext());
  55.     }
  56.     /**
  57.      * @param UpdateContext $updateContext
  58.      * @return void
  59.      */
  60.     public function update(UpdateContext $updateContext): void
  61.     {
  62.         if (version_compare($updateContext->getCurrentPluginVersion(), '3.0.11''<=')) {
  63.             try {
  64.                 $this->changeIntegrationAndRoleName($updateContext->getContext());
  65.             } catch (\Throwable $exception) {
  66.             }
  67.         }
  68.     }
  69.     /**
  70.      * @param UpdateContext $updateContext
  71.      * @return void
  72.      */
  73.     public function postUpdate(UpdateContext $updateContext): void
  74.     {
  75.         $apiClientService $this->getApiClientService($updateContext->getCurrentShopwareVersion());
  76.         try {
  77.             $userConnectionIds $this->getAllUserConnectionIds($updateContext->getContext());
  78.             $data = [
  79.                 'plugin_version' => $updateContext->getUpdatePluginVersion(),
  80.                 'shop_version' => $updateContext->getCurrentShopwareVersion()
  81.             ];
  82.             foreach ($userConnectionIds as $userConnectionId) {
  83.                 $apiClientService->pluginUpdated($data$userConnectionId$updateContext->getContext());
  84.             }
  85.         } catch (\Throwable $e) {
  86.             $apiClientService->getLogger()->addRecord(Logger::ERROR$e->getMessage());
  87.         }
  88.     }
  89.     /**
  90.      * @param DeactivateContext $deactivateContext
  91.      */
  92.     public function deactivate(DeactivateContext $deactivateContext): void
  93.     {
  94.         $this->removeSIBSmtpSettings($deactivateContext->getContext());
  95.     }
  96.     /**
  97.      * @param UninstallContext $uninstallContext
  98.      */
  99.     public function uninstall(UninstallContext $uninstallContext): void
  100.     {
  101.         if (!$uninstallContext->keepUserData()) {
  102.             $this->deleteIntegrations($uninstallContext->getContext());
  103.             $this->deleteAclRole($uninstallContext->getContext());
  104.             $this->deleteAllSendinblueConfigs($uninstallContext->getContext());
  105.             $this->deleteTables();
  106.         }
  107.     }
  108.     /**
  109.      * @param Context $context
  110.      * @return string
  111.      */
  112.     private function createAclRole(Context $context)
  113.     {
  114.         $id md5(self::ACL_ROLE_NAME);
  115.         $roleData = [
  116.             'id' => $id,
  117.             'name' => self::ACL_ROLE_NAME,
  118.             'privileges' => ["customer.editor""customer.viewer""customer:read""customer:update""newsletter_recipient.creator""newsletter_recipient.deleter""newsletter_recipient.editor""newsletter_recipient.viewer""newsletter_recipient:create""newsletter_recipient:delete""newsletter_recipient:read""newsletter_recipient:update"]
  119.         ];
  120.         $aclRoleRepository $this->container->get('acl_role.repository');
  121.         $context->scope(Context::SYSTEM_SCOPE, function (Context $context) use ($aclRoleRepository$roleData): void {
  122.             $aclRoleRepository->upsert([$roleData], $context);
  123.         });
  124.         return $id;
  125.     }
  126.     /**
  127.      * @param Context $context
  128.      */
  129.     private function createIntegrations(Context $context): void
  130.     {
  131.         $this->getIntegrationService()->createIntegration(self::INTEGRATION_LABEL$context);
  132.     }
  133.     /**
  134.      * @param Context $context
  135.      */
  136.     private function deleteIntegrations(Context $context): void
  137.     {
  138.         $this->getIntegrationService()->deleteIntegrations($context);
  139.     }
  140.     /**
  141.      * @param Context $context
  142.      */
  143.     private function deleteAclRole(Context $context)
  144.     {
  145.         $aclRoleRepository $this->container->get('acl_role.repository');
  146.         $context->scope(Context::SYSTEM_SCOPE, function (Context $context) use ($aclRoleRepository): void {
  147.             $aclRoleRepository->delete([['id' => md5(self::ACL_ROLE_NAME)]], $context);
  148.             $aclRoleRepository->delete([['id' => md5(self::OLD_ACL_ROLE_NAME)]], $context);
  149.         });
  150.     }
  151.     private function deleteAllSendinblueConfigs(Context $context): void
  152.     {
  153.         /** @var EntityRepositoryInterface $systemConfigRepository */
  154.         $systemConfigRepository $this->container->get('system_config.repository');
  155.         $this->removeSIBSmtpSettings($context);
  156.         $criteria = new Criteria();
  157.         $criteria->addFilter(new ContainsFilter('configurationKey'ConfigService::CONFIG_PREFIX));
  158.         $systemConfigIds $systemConfigRepository->searchIds($criteria$context)->getIds();
  159.         if (empty($systemConfigIds)) {
  160.             return;
  161.         }
  162.         $ids array_map(static function ($id) {
  163.             return ['id' => $id];
  164.         }, $systemConfigIds);
  165.         $systemConfigRepository->delete($ids$context);
  166.     }
  167.     /**
  168.      * @param Context $context
  169.      * @return void
  170.      */
  171.     private function removeSIBSmtpSettings(Context $context): void
  172.     {
  173.         /** @var EntityRepositoryInterface $systemConfigRepository */
  174.         $systemConfigRepository $this->container->get('system_config.repository');
  175.         $criteria = new Criteria();
  176.         $criteria->addFilter(new EqualsFilter('configurationKey'ConfigService::prepareConfigName(ConfigService::CONFIG_IS_SMTP_ENABLED)));
  177.         $systemConfigs $systemConfigRepository->search($criteria$context)->getElements();
  178.         if (empty($systemConfigs)) {
  179.             return;
  180.         }
  181.         /** @var SystemConfigService $systemConfigService */
  182.         $systemConfigService $this->container->get(SystemConfigService::class);
  183.         $smtpConfigs = [
  184.             ConfigService::CORE_MAILER_AGENT_CONFIG,
  185.             ConfigService::CORE_MAILER_HOST_CONFIG,
  186.             ConfigService::CORE_MAILER_PORT_CONFIG,
  187.             ConfigService::CORE_MAILER_USERNAME_CONFIG,
  188.             ConfigService::CORE_MAILER_PASSWORD_CONFIG,
  189.             ConfigService::CORE_MAILER_SENDER_CONFIG,
  190.             ConfigService::CORE_MAILER_ENCRYPTION_CONFIG,
  191.             ConfigService::CORE_MAILER_AUTHENTICATION_CONFIG
  192.         ];
  193.         foreach ($systemConfigs as $systemConfig) {
  194.             if ($systemConfig->getConfigurationValue()) {
  195.                 $salesChannelId $systemConfig->getSalesChannelId();
  196.                 foreach ($smtpConfigs as $config) {
  197.                     $systemConfigService->delete($config$salesChannelId);
  198.                 }
  199.             }
  200.         }
  201.         foreach ($smtpConfigs as $config) {
  202.             $systemConfigService->delete($config);
  203.         }
  204.     }
  205.     /**
  206.      * @return IntegrationService|null
  207.      */
  208.     private function getIntegrationService(): ?IntegrationService
  209.     {
  210.         if (empty($this->integrationService)) {
  211.             if ($this->container->has(IntegrationService::class)) {
  212.                 /** @var IntegrationService integrationService */
  213.                 $this->integrationService $this->container->get(IntegrationService::class);
  214.             } else {
  215.                 /** @var EntityRepositoryInterface $integrationRepository */
  216.                 $integrationRepository $this->container->get('integration.repository');
  217.                 /** @var EntityRepositoryInterface $aclRoleRepository */
  218.                 $aclRoleRepository $this->container->get('acl_role.repository');
  219.                 /** @var SystemConfigService $systemConfigService */
  220.                 $systemConfigService $this->container->get(SystemConfigService::class);
  221.                 $this->integrationService = new IntegrationService($integrationRepository$aclRoleRepository$systemConfigService);
  222.             }
  223.         }
  224.         return $this->integrationService;
  225.     }
  226.     /**
  227.      * @param Context $context
  228.      * @return void
  229.      */
  230.     private function changeIntegrationAndRoleName(Context $context): void
  231.     {
  232.         $connection $this->container->get(Connection::class);
  233.         // change acl_role name
  234.         try {
  235.             $connection->update('acl_role',
  236.                 ['name' => self::ACL_ROLE_NAME],
  237.                 ['name' => self::OLD_ACL_ROLE_NAME]
  238.             );
  239.         } catch (\Throwable $e) {
  240.         }
  241.         // change integration name
  242.         try {
  243.             $integrationRepository $this->container->get('integration.repository');
  244.             $criteria = new Criteria();
  245.             $criteria->addFilter(new EqualsFilter('customFields.sendinblue'1));
  246.             $integrations $integrationRepository->search($criteria$context);
  247.             $data = [];
  248.             foreach ($integrations as $integration) {
  249.                 $data[] = [
  250.                     'id' => $integration->getId(),
  251.                     'label' => str_replace(self::OLD_INTEGRATION_LABELself::INTEGRATION_LABEL$integration->getLabel())
  252.                 ];
  253.             }
  254.             if (!empty($data)) {
  255.                 $integrationRepository->update($data$context);
  256.             }
  257.         } catch (\Throwable $e) {
  258.         }
  259.     }
  260.     /**
  261.      * @param string $currentSwVersion
  262.      * @return ApiClientService
  263.      */
  264.     private function getApiClientService(string $currentSwVersion): ApiClientService
  265.     {
  266.         $configService = new ConfigService(
  267.             $this->container->get('Shopware\Core\System\SystemConfig\SystemConfigService'),
  268.             ApiClientService::SIB_BASE_URL
  269.         );
  270.         $logger = new Logger('Sendinblue');
  271.         $versionProvider = new VersionProvider(
  272.             $currentSwVersion,
  273.             $this->container->get('plugin.repository')
  274.         );
  275.         return new ApiClientService($configService$logger$versionProvider);
  276.     }
  277.     /**
  278.      * @param Context $context
  279.      * @return array
  280.      */
  281.     private function getAllUserConnectionIds(Context $context): array
  282.     {
  283.         $configRepo $this->container->get('system_config.repository');
  284.         $criteria = new Criteria();
  285.         $criteria->addFilter(new EqualsFilter(
  286.                 'configurationKey',
  287.                 ConfigService::CONFIG_PREFIX ConfigService::CONFIG_USER_CONNECTION_ID)
  288.         );
  289.         $sendinblueConfigs $configRepo->search($criteria$context);
  290.         return $sendinblueConfigs->fmap(function (SystemConfigEntity $configEntity) {
  291.             return $configEntity->getConfigurationValue();
  292.         });
  293.     }
  294.     private function deleteTables()
  295.     {
  296.         $connection $this->container->get(Connection::class);
  297.         foreach (self::CUSTOM_TABLES as $table) {
  298.             try {
  299.                 $connection->executeStatement('DROP TABLE IF EXISTS `' $table'`;');
  300.             } catch (Exception $exception) {
  301.             }
  302.         }
  303.     }
  304. }