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

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Acris\ShopSwitch;
  3. use Acris\ShopSwitch\Core\Content\ShopSwitch\Event\ShopSwitchDatabaseUpdateEvent;
  4. use Acris\ShopSwitch\Custom\ShopSwitchExclusionDefinition;
  5. use Acris\ShopSwitch\Custom\ShopSwitchRuleEntity;
  6. use Doctrine\DBAL\Connection;
  7. use Shopware\Core\Content\ImportExport\Aggregate\ImportExportLog\ImportExportLogEntity;
  8. use Shopware\Core\Content\ImportExport\ImportExportProfileEntity;
  9. use Shopware\Core\Content\MailTemplate\MailTemplateActions;
  10. use Shopware\Core\Defaults;
  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\EntitySearchResult;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
  16. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  17. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
  18. use Shopware\Core\Framework\DataAbstractionLayer\Search\IdSearchResult;
  19. use Shopware\Core\Framework\Plugin;
  20. use Shopware\Core\Framework\Plugin\Context\ActivateContext;
  21. use Shopware\Core\Framework\Plugin\Context\UninstallContext;
  22. use Shopware\Core\Framework\Plugin\Context\UpdateContext;
  23. use Shopware\Core\Framework\Uuid\Uuid;
  24. use Shopware\Core\System\SalesChannel\Aggregate\SalesChannelType\SalesChannelTypeEntity;
  25. class AcrisShopSwitchCS extends Plugin
  26. {
  27.     const DEFAULT_PRODUCT_IMPORT_NAME "ACRIS_IP_Targeting_and_Language_Detection_Exclusions";
  28.     const DEFAULT_PRODUCT_IMPORT_NAME_EN "ACRIS IP Targeting and Language Detection: Exclusions";
  29.     const DEFAULT_PRODUCT_IMPORT_NAME_DE "ACRIS IP Targeting und Spracherkennung: Ausnahmen";
  30.     const DEFAULT_MAIL_TEMPLATE_TYPE_DATABASE_UPDATE_FAILED 'shopSwitchDatabaseUpdateFailed';
  31.     public function activate(ActivateContext $activateContext): void
  32.     {
  33.         $this->insertDefaultData($activateContext->getContext(), true);
  34.     }
  35.     public function postUpdate(UpdateContext $updateContext): void
  36.     {
  37.         if(version_compare($updateContext->getCurrentPluginVersion(), '2.1.0''<')
  38.             || (version_compare($updateContext->getCurrentPluginVersion(), '3.8.0''<') && version_compare($updateContext->getUpdatePluginVersion(), '3.8.0''>='))
  39.             || (version_compare($updateContext->getCurrentPluginVersion(), '3.8.2''<') && version_compare($updateContext->getUpdatePluginVersion(), '3.8.2''>='))) {
  40.             $this->insertDefaultData($updateContext->getContext(), $updateContext->getPlugin()->isActive());
  41.         }
  42.         if(version_compare($updateContext->getCurrentPluginVersion(), '3.4.0''<') && version_compare($updateContext->getUpdatePluginVersion(), '3.4.0''>=')) {
  43.             $this->addTranslationsNewFields($updateContext->getContext(), $updateContext->getPlugin()->isActive());
  44.         }
  45.     }
  46.     public function uninstall(UninstallContext $context): void
  47.     {
  48.         if ($context->keepUserData()) {
  49.             return;
  50.         }
  51.         $this->cleanupDatabase();
  52.         $this->removeDefaultMailTemplate($context->getContext());
  53.         $this->removeImportExportProfiles($context->getContext());
  54.     }
  55.     private function insertDefaultData(Context $contextbool $isActive): void
  56.     {
  57.         $this->insertDefaultMailTemplate($context);
  58.         $this->insertDefaultImportProfile($context);
  59.         $this->insertDefaultExclusions($context$isActive);
  60.     }
  61.     private function cleanupDatabase(): void
  62.     {
  63.         $connection $this->container->get(Connection::class);
  64.         $connection->executeStatement('DROP TABLE IF EXISTS acris_switch_domain_language_whitelist');
  65.         $connection->executeStatement('DROP TABLE IF EXISTS acris_switch_domain_language_blacklist');
  66.         $connection->executeStatement('DROP TABLE IF EXISTS acris_switch_domain_country_whitelist');
  67.         $connection->executeStatement('DROP TABLE IF EXISTS acris_switch_domain_country_blacklist');
  68.         $connection->executeStatement('DROP TABLE IF EXISTS acris_switch_domain_translation');
  69.         $connection->executeStatement('DROP TABLE IF EXISTS acris_switch_domain');
  70.         $connection->executeStatement('DROP TABLE IF EXISTS acris_switch_rule_translation');
  71.         $connection->executeStatement('DROP TABLE IF EXISTS acris_switch_rule');
  72.         $connection->executeStatement('DROP TABLE IF EXISTS acris_switch_exclusion');
  73.     }
  74.     private function insertDefaultMailTemplate(Context $context)
  75.     {
  76.         $mailTemplateTypeRepository $this->container->get('mail_template_type.repository');
  77.         $salesChannels $this->getSalesChannels($context);
  78.         // Shop switch database update failed
  79.         /** @var IdSearchResult $mailTemplateTypeDatabaseUpdateFailedSearchResult */
  80.         $mailTemplateTypeDatabaseUpdateFailedSearchResult $mailTemplateTypeRepository->searchIds((new Criteria())->addFilter(new EqualsFilter('technicalName'self::DEFAULT_MAIL_TEMPLATE_TYPE_DATABASE_UPDATE_FAILED)), $context);
  81.         if(empty($mailTemplateTypeDatabaseUpdateFailedSearchResult->firstId())) {
  82.             $mailTemplateTypeDatabaseUpdateFailedId Uuid::randomHex();
  83.             $mailTemplateDatabaseUpdateFailedId Uuid::randomHex();
  84.             $mailTemplateTypeDatabaseUpdateFailedData = [
  85.                 'id' => $mailTemplateTypeDatabaseUpdateFailedId,
  86.                 'technicalName' => self::DEFAULT_MAIL_TEMPLATE_TYPE_DATABASE_UPDATE_FAILED,
  87.                 'availableEntities' => ['salesChannel' => 'sales_channel'],
  88.                 'translations' => [
  89.                     'de-DE' => [
  90.                         'name' => 'ACRIS Automatisches Update der IP-Zieldatenbank fehlgeschlagen'
  91.                     ],
  92.                     'en-GB' => [
  93.                         'name' => 'ACRIS IP Targeting Database Automatically Update Failed'
  94.                     ],
  95.                     [
  96.                         'name' => 'ACRIS IP Targeting Database Automatically Update Failed',
  97.                         'languageId' => Defaults::LANGUAGE_SYSTEM
  98.                     ]
  99.                 ],
  100.                 'mailTemplates' => [
  101.                     [
  102.                         'id' => $mailTemplateDatabaseUpdateFailedId,
  103.                         'systemDefault' => true,
  104.                         'translations' => [
  105.                             'de-DE' => [
  106.                                 'senderName' => '{{ salesChannel.name }}',
  107.                                 'subject' => 'Automatisches Update der IP-Zieldatenbank fehlgeschlagen',
  108.                                 'description' => 'E-Mail mit der Information, dass die automatische Aktualisierung der IP-Zieldatenbank fehlgeschlagen ist.',
  109.                                 'contentHtml' => file_get_contents($this->path '/Resources/mail-template/html/de-DE/shop-switch-database-update-failed.html.twig'),
  110.                                 'contentPlain' => file_get_contents($this->path '/Resources/mail-template/plain/de-DE/shop-switch-database-update-failed.html.twig')
  111.                             ],
  112.                             'en-GB' => [
  113.                                 'senderName' => '{{ salesChannel.name }}',
  114.                                 'subject' => 'IP targeting database automatically update failed',
  115.                                 'description' => 'E-mail informing that IP targeting database automatically update failed.',
  116.                                 'contentHtml' => file_get_contents($this->path '/Resources/mail-template/html/en-GB/shop-switch-database-update-failed.html.twig'),
  117.                                 'contentPlain' => file_get_contents($this->path '/Resources/mail-template/plain/en-GB/shop-switch-database-update-failed.html.twig')
  118.                             ],
  119.                             [
  120.                                 'senderName' => '{{ salesChannel.name }}',
  121.                                 'subject' => 'IP targeting database automatically update failed',
  122.                                 'description' => 'E-mail informing that IP targeting database automatically update failed.',
  123.                                 'contentHtml' => file_get_contents($this->path '/Resources/mail-template/html/en-GB/shop-switch-database-update-failed.html.twig'),
  124.                                 'contentPlain' => file_get_contents($this->path '/Resources/mail-template/plain/en-GB/shop-switch-database-update-failed.html.twig'),
  125.                                 'languageId' => Defaults::LANGUAGE_SYSTEM
  126.                             ]
  127.                         ]
  128.                     ]
  129.                 ]
  130.             ];
  131.             $mailTemplateTypeRepository->upsert([$mailTemplateTypeDatabaseUpdateFailedData], $context);
  132.             $eventActionRepository $this->container->get('event_action.repository');
  133.             $eventActionRepository->upsert([[
  134.                 'eventName' => ShopSwitchDatabaseUpdateEvent::EVENT_NAME,
  135.                 'actionName' => MailTemplateActions::MAIL_TEMPLATE_MAIL_SEND_ACTION,
  136.                 'config' => ['mail_template_type_id' => $mailTemplateTypeDatabaseUpdateFailedId'mail_template_id' => $mailTemplateDatabaseUpdateFailedId],
  137.                 'salesChannels' => $salesChannels
  138.             ]], $context);
  139.         }
  140.     }
  141.     private function removeDefaultMailTemplate(Context $context)
  142.     {
  143.         $mailTemplateTypeRepository $this->container->get('mail_template_type.repository');
  144.         /** @var IdSearchResult $mailTemplateTypeStockNotificationSearchResult */
  145.         $mailTemplateTypeStockNotificationSearchResult $mailTemplateTypeRepository->searchIds((new Criteria())->addFilter(new EqualsAnyFilter('technicalName', [self::DEFAULT_MAIL_TEMPLATE_TYPE_DATABASE_UPDATE_FAILED])), $context);
  146.         if($mailTemplateTypeStockNotificationSearchResult->firstId()) {
  147.             $mailTemplateRepository $this->container->get('mail_template.repository');
  148.             $deleteTemplateTypeData = [];
  149.             $deleteTemplateData = [];
  150.             foreach ($mailTemplateTypeStockNotificationSearchResult->getIds() as $templateTypeId) {
  151.                 /** @var IdSearchResult $mailTemplateSearchResult */
  152.                 $mailTemplateSearchResult $mailTemplateRepository->searchIds((new Criteria())->addFilter(new EqualsFilter('mailTemplateTypeId'$templateTypeId)), $context);
  153.                 if ($mailTemplateSearchResult->firstId()) {
  154.                     foreach ($mailTemplateSearchResult->getIds() as $id) {
  155.                         $deleteTemplateData[] = ['id' => $id];
  156.                     }
  157.                 }
  158.                 $deleteTemplateTypeData[] = ['id' => $templateTypeId];
  159.             }
  160.             if (!empty($deleteTemplateData)) {
  161.                 $mailTemplateRepository->delete($deleteTemplateData$context);
  162.             }
  163.             if (!empty($deleteTemplateTypeData)) {
  164.                 $mailTemplateTypeRepository->delete($deleteTemplateTypeData$context);
  165.             }
  166.         }
  167.         $eventActionRepository $this->container->get('event_action.repository');
  168.         /** @var IdSearchResult $eventActionSearchResult */
  169.         $eventActionSearchResult $eventActionRepository->searchIds((new Criteria())->addFilter(new EqualsAnyFilter('eventName', [ShopSwitchDatabaseUpdateEvent::EVENT_NAME])), $context);
  170.         if($eventActionSearchResult->firstId()) {
  171.             $deleteBusinessEvents = [];
  172.             foreach ($eventActionSearchResult->getIds() as $id) {
  173.                 $deleteBusinessEvents[] = ['id' => $id];
  174.             }
  175.             if (!empty($deleteBusinessEvents)) {
  176.                 $eventActionRepository->delete($deleteBusinessEvents$context);
  177.             }
  178.         }
  179.     }
  180.     private function getSalesChannels(Context $context): array
  181.     {
  182.         /** @var EntityRepositoryInterface $salesChannelTypeRepository */
  183.         $salesChannelTypeRepository $this->container->get('sales_channel_type.repository');
  184.         /** @var EntityRepositoryInterface $salesChannelRepository */
  185.         $salesChannelRepository $this->container->get('sales_channel.repository');
  186.         /** @var SalesChannelTypeEntity $salesChannelType */
  187.         $salesChannelType $salesChannelTypeRepository->search((new Criteria())->addFilter(new EqualsFilter('id'Defaults::SALES_CHANNEL_TYPE_STOREFRONT)), $context)->first();
  188.         if (!$salesChannelType) return [];
  189.         $salesChannelIds = [];
  190.         $salesChannelResult $salesChannelRepository->searchIds((new Criteria())->addFilter(new EqualsFilter('typeId'$salesChannelType->getId())), $context);
  191.         if ($salesChannelResult->firstId()) {
  192.             foreach ($salesChannelResult->getIds() as $id) {
  193.                 $salesChannelIds[] = ['id' => $id];
  194.             }
  195.         }
  196.         return $salesChannelIds;
  197.     }
  198.     private function addTranslationsNewFields(Context $contextbool $true)
  199.     {
  200.         /** @var EntityRepositoryInterface $shopSwitchRuleRepository */
  201.         $shopSwitchRuleRepository $this->container->get('acris_switch_rule.repository');
  202.         $shopSwitchRuleResult $shopSwitchRuleRepository->search(new Criteria(), $context);
  203.         /** @var ShopSwitchRuleEntity $shopSwitchRuleEntity */
  204.         foreach ($shopSwitchRuleResult->getElements() as $shopSwitchRuleEntity) {
  205.             $shopSwitchRuleRepository->upsert([[
  206.                 'id' => $shopSwitchRuleEntity->getId(),
  207.                 'translations' => [
  208.                     'de-DE' => [
  209.                         'textButton' => 'Bestätigen',
  210.                         'labelCountry' => 'Land',
  211.                         'labelLanguage' => 'Sprache'
  212.                     ],
  213.                     'en-GB' => [
  214.                         'textButton' => 'Enter',
  215.                         'labelCountry' => 'Country',
  216.                         'labelLanguage' => 'Language'
  217.                     ],
  218.                     [
  219.                         'textButton' => 'Enter',
  220.                         'labelCountry' => 'Country',
  221.                         'labelLanguage' => 'Language',
  222.                         'languageId' => Defaults::LANGUAGE_SYSTEM
  223.                     ]
  224.                 ],
  225.             ]], $context);
  226.         }
  227.     }
  228.     private function insertDefaultImportProfile(Context $context)
  229.     {
  230.         /** @var EntityRepositoryInterface $profileRepository */
  231.         $profileRepository $this->container->get('import_export_profile.repository');
  232.         $defaultProfiles = [
  233.             [
  234.                 'name' => self::DEFAULT_PRODUCT_IMPORT_NAME,
  235.                 'fileType' => 'text/csv',
  236.                 'delimiter' => ';',
  237.                 'enclosure' => '"',
  238.                 'sourceEntity' => 'acris_switch_exclusion',
  239.                 'mapping' => $this->getDefaultImportProfileMappingData(),
  240.                 'systemDefault' => false,
  241.                 'translations' => [
  242.                     'de-DE' => [
  243.                         'label' => self::DEFAULT_PRODUCT_IMPORT_NAME_DE
  244.                     ],
  245.                     'en-GB' => [
  246.                         'label' => self::DEFAULT_PRODUCT_IMPORT_NAME_EN
  247.                     ],
  248.                     [
  249.                         'label' => self::DEFAULT_PRODUCT_IMPORT_NAME_EN,
  250.                         'languageId' => Defaults::LANGUAGE_SYSTEM
  251.                     ]
  252.                 ]
  253.             ]
  254.         ];
  255.         foreach ($defaultProfiles as $defaultProfile) {
  256.             $this->createImportProfileIfNotExists($profileRepository$context$defaultProfile);
  257.         }
  258.     }
  259.     private function getDefaultImportProfileMappingData()
  260.     {
  261.         return array(
  262.             ["id"=>"ae49a685ac014e2a8bd863265fa10a00","key"=>"id","mappedKey"=>"id"],["id"=>"8422635b72574b5f82c43ccd571ea923","key"=>"active","mappedKey"=>"active"],["id"=>"dec83b5346444670a6343272829152eb","key"=>"type","mappedKey"=>"type"],["id"=>"ec08e8124ea1468caca7f5c0468684e3","key"=>"searchUrlBy","mappedKey"=>"searchUrlBy"],["id"=>"4137c60c60ec4031b570b6ad656d324d","key"=>"regex","mappedKey"=>"regex"],["id"=>"f576d1d12c6745f78b53d9348657eeed","key"=>"url","mappedKey"=>"url"],["id"=>"e246779168634e3d84498edb34585c17","key"=>"ip","mappedKey"=>"ip"]
  263.         );
  264.     }
  265.     private function createImportProfileIfNotExists(EntityRepositoryInterface $entityRepositoryContext $context, array $profileData): void
  266.     {
  267.         $exists $entityRepository->search((new Criteria())->addFilter(new EqualsFilter('name'$profileData['name'])), $context);
  268.         if($exists->getTotal() === 0) {
  269.             $entityRepository->create([$profileData], $context);
  270.         }
  271.     }
  272.     private function removeImportExportProfiles(Context $context): void
  273.     {
  274.         $connection $this->container->get(Connection::class);
  275.         $importExportProfileRepository $this->container->get('import_export_profile.repository');
  276.         $importExportLogRepository $this->container->get('import_export_log.repository');
  277.         /** @var EntitySearchResult $searchResult */
  278.         $searchResult $importExportProfileRepository->search((new Criteria())->addFilter(new MultiFilter(MultiFilter::CONNECTION_AND, [
  279.             new EqualsFilter('sourceEntity''product'),
  280.             new MultiFilter(MultiFilter::CONNECTION_OR, [
  281.                 new EqualsFilter('name'self::DEFAULT_PRODUCT_IMPORT_NAME)
  282.             ])
  283.         ])), $context);
  284.         $ids = [];
  285.         /** @var \Shopware\Core\Framework\Uuid\Uuid $uuid */
  286.         $uuid = new \Shopware\Core\Framework\Uuid\Uuid();
  287.         if($searchResult->getTotal() > && $searchResult->first()) {
  288.             /** @var ImportExportProfileEntity $entity */
  289.             foreach ($searchResult->getEntities()->getElements() as $entity) {
  290.                 if ($entity->getSystemDefault() === true) {
  291.                     $importExportProfileRepository->update([
  292.                         ['id' => $entity->getId(), 'systemDefault' => false ]
  293.                     ], $context);
  294.                 }
  295.                 /** @var EntitySearchResult $logResult */
  296.                 $logResult $importExportLogRepository->search((new Criteria())->addFilter(new EqualsFilter('profileId'$entity->getId())), $context);
  297.                 if ($logResult->getTotal() > && $logResult->first()) {
  298.                     /** @var ImportExportLogEntity $logEntity */
  299.                     foreach ($logResult->getEntities() as $logEntity) {
  300.                         $stmt $connection->prepare("UPDATE import_export_log SET profile_id = :profileId WHERE id = :id");
  301.                         $stmt->execute(['profileId' => null'id' => $uuid::fromHexToBytes($logEntity->getId()) ]);
  302.                     }
  303.                 }
  304.                 $ids[] = ['id' => $entity->getId()];
  305.             }
  306.             $importExportProfileRepository->delete($ids$context);
  307.         }
  308.     }
  309.     private function insertDefaultExclusions(Context $contextbool $isActive): void
  310.     {
  311.         if($isActive !== true) {
  312.             return;
  313.         }
  314.         $exclusionRepository $this->container->get('acris_switch_exclusion.repository');
  315.         $data = [
  316.             'active' => true,
  317.             'type' => ShopSwitchExclusionDefinition::EXCLUSION_TYPE_URL,
  318.             'searchUrlBy' => ShopSwitchExclusionDefinition::EXCLUSION_SEARCH_URL_BY_REGEX,
  319.             'regex' => '\/stripe-payment\/'
  320.         ];
  321.         $this->createIfNotExists($exclusionRepository, [['name' => 'regex''value' => $data['regex']]], $data$context);
  322.     }
  323.     private function createIfNotExists(EntityRepositoryInterface $repository, array $equalFields, array $dataContext $context)
  324.     {
  325.         $filters = [];
  326.         foreach ($equalFields as $equalField) {
  327.             $filters[] = new EqualsFilter($equalField['name'], $equalField['value']);
  328.         }
  329.         if(sizeof($filters) > 1) {
  330.             $filter = new MultiFilter(MultiFilter::CONNECTION_OR$filters);
  331.         } else {
  332.             $filter array_shift($filters);
  333.         }
  334.         $searchResult $repository->search((new Criteria())->addFilter($filter), $context);
  335.         if($searchResult->count() == 0) {
  336.             $repository->create([$data], $context);
  337.         }
  338.     }
  339. }