custom/plugins/AcrisDiscountGroupCS/src/AcrisDiscountGroupCS.php line 22

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Acris\DiscountGroup;
  3. use Doctrine\DBAL\Connection;
  4. use Shopware\Core\Content\ImportExport\ImportExportProfileEntity;
  5. use Shopware\Core\Defaults;
  6. use Shopware\Core\Framework\Context;
  7. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
  12. use Shopware\Core\Framework\Plugin;
  13. use Shopware\Core\Framework\Plugin\Context\InstallContext;
  14. use Shopware\Core\Framework\Plugin\Context\UninstallContext;
  15. use Shopware\Core\Framework\Plugin\Context\UpdateContext;
  16. use Shopware\Core\Framework\Uuid\Uuid;
  17. use Shopware\Core\System\CustomField\CustomFieldTypes;
  18. use Shopware\Core\System\Snippet\SnippetEntity;
  19. class AcrisDiscountGroupCS extends Plugin
  20. {
  21.     /** @deprecated  */
  22.     const CUSTOM_FIELD_SET_NAME_DISCOUNT_GROUP 'acris_discount_group';
  23.     const CUSTOM_FIELD_SET_NAME_CUSTOMER_DISCOUNT_GROUP 'acris_discount_group_customer';
  24.     const CUSTOM_FIELD_SET_NAME_PRODUCT_DISCOUNT_GROUP 'acris_discount_group_product';
  25.     const IMPORT_EXPORT_PROFILE_NAME 'ACRIS Discount Groups';
  26.     const DEFAULT_MAIL_TEMPLATE_TYPE_DISCOUNT_GROUP 'acris_discount_group.discount_group';
  27.     public function install(InstallContext $context): void
  28.     {
  29.         $this->addCustomFields($context->getContext());
  30.         $this->addImportExportProfile($context->getContext());
  31.     }
  32.     public function activate(Plugin\Context\ActivateContext $context): void
  33.     {
  34.         $this->insertDefaultMailTemplate($context->getContext());
  35.     }
  36.     public function postUpdate(UpdateContext $updateContext): void
  37.     {
  38.         if(version_compare($updateContext->getCurrentPluginVersion(), '1.2.0''<') && $updateContext->getPlugin()->isActive() === true) {
  39.             $this->addImportExportProfile($updateContext->getContext());
  40.         }
  41.         if(version_compare($updateContext->getCurrentPluginVersion(), '1.4.0''<')
  42.             && version_compare($updateContext->getUpdatePluginVersion(), '1.4.0''>=')) {
  43.             $this->addCustomFields($updateContext->getContext());
  44.         }
  45.         $this->insertDefaultMailTemplate($updateContext->getContext());
  46.     }
  47.     public function uninstall(UninstallContext $context): void
  48.     {
  49.         if ($context->keepUserData()) {
  50.             return;
  51.         }
  52.         $this->cleanupImportExportProfile($context->getContext());
  53.         $this->removeCustomFields($context->getContext(), [self::CUSTOM_FIELD_SET_NAME_DISCOUNT_GROUPself::CUSTOM_FIELD_SET_NAME_PRODUCT_DISCOUNT_GROUPself::CUSTOM_FIELD_SET_NAME_CUSTOMER_DISCOUNT_GROUP]);
  54.         $this->cleanupDatabase();
  55.         $this->removeDefaultMailTemplate($context->getContext());
  56.     }
  57.     private function cleanupDatabase(): void
  58.     {
  59.         $connection $this->container->get(Connection::class);
  60.         $connection->executeStatement('DROP TABLE IF EXISTS acris_discount_group_rule');
  61.         $connection->executeStatement('DROP TABLE IF EXISTS acris_discount_dynamic_groups');
  62.         $connection->executeStatement('DROP TABLE IF EXISTS acris_discount_group_translation');
  63.         $connection->executeStatement('DROP TABLE IF EXISTS acris_discount_group');
  64.         $connection->executeUpdate('ALTER TABLE `rule` DROP COLUMN `acrisDiscountGroups`');
  65.         $connection->executeUpdate('ALTER TABLE `product_stream` DROP COLUMN `acrisDiscountGroups`');
  66.         $connection->executeUpdate('ALTER TABLE `product` DROP COLUMN `acrisDiscountGroups`');
  67.         $connection->executeUpdate('ALTER TABLE `customer` DROP COLUMN `acrisDiscountGroups`');
  68.     }
  69.     private function addCustomFields(Context $context): void
  70.     {
  71.         /* Check for snippets if they exist for custom fields */
  72.         $this->checkForExistingCustomFieldSnippets($context);
  73.         $this->removeCustomFields($context, [self::CUSTOM_FIELD_SET_NAME_DISCOUNT_GROUP]);
  74.         $customFieldSet $this->container->get('custom_field_set.repository');
  75.         if($customFieldSet->search((new Criteria())->addFilter(new EqualsFilter('name'self::CUSTOM_FIELD_SET_NAME_CUSTOMER_DISCOUNT_GROUP)), $context)->count() == 0) {
  76.             $customFieldSet->create([[
  77.                 'name' => self::CUSTOM_FIELD_SET_NAME_CUSTOMER_DISCOUNT_GROUP,
  78.                 'config' => [
  79.                     'label' => [
  80.                         'en-GB' => 'Customer discount group',
  81.                         'de-DE' => 'Kunden-Rabattgruppe'
  82.                     ]
  83.                 ],
  84.                 'customFields' => [
  85.                     ['name' => 'acris_discount_group_customer_value''type' => CustomFieldTypes::TEXT,
  86.                         'config' => [
  87.                             'componentName' => 'sw-field',
  88.                             'type' => 'text',
  89.                             'customFieldType' => 'text',
  90.                             'customFieldPosition' => 1,
  91.                             'label' => [
  92.                                 'en-GB' => 'Customer discount group',
  93.                                 'de-DE' => 'Kunden-Rabattgruppe'
  94.                             ],
  95.                             'helpText' => [
  96.                                 'en-GB' => 'The customer discount group can be used via the ACRIS plugin to allow multiple customers with the same customer discount group to receive a discount.',
  97.                                 'de-DE' => 'Die Kunden-Rabattgruppe kann über das ACRIS Plugin verwendet werden, um mehreren Kunden mit derselben Kunden-Rabattgruppe einen Rabatt zu ermöglichen.'
  98.                             ]
  99.                         ]]
  100.                 ],
  101.                 'relations' => [
  102.                     [
  103.                         'entityName' => 'customer'
  104.                     ]
  105.                 ]
  106.             ]], $context);
  107.         };
  108.         if($customFieldSet->search((new Criteria())->addFilter(new EqualsFilter('name'self::CUSTOM_FIELD_SET_NAME_PRODUCT_DISCOUNT_GROUP)), $context)->count() == 0) {
  109.             $customFieldSet->create([[
  110.                 'name' => self::CUSTOM_FIELD_SET_NAME_PRODUCT_DISCOUNT_GROUP,
  111.                 'config' => [
  112.                     'label' => [
  113.                         'en-GB' => 'Merchandise group (discount group)',
  114.                         'de-DE' => 'Warengruppe (Rabattgruppe)'
  115.                     ]
  116.                 ],
  117.                 'customFields' => [
  118.                     ['name' => 'acris_discount_group_product_value''type' => CustomFieldTypes::TEXT,
  119.                         'config' => [
  120.                             'componentName' => 'sw-field',
  121.                             'type' => 'text',
  122.                             'customFieldType' => 'text',
  123.                             'customFieldPosition' => 1,
  124.                             'label' => [
  125.                                 'en-GB' => 'Merchandise group (discount group)',
  126.                                 'de-DE' => 'Warengruppe (Rabattgruppe)'
  127.                             ],
  128.                             'helpText' => [
  129.                                 'en-GB' => 'The merchandise group (discount group) can be used via the ACRIS plugin to allow all products with the same merchandise group (discount group) to receive a discount.',
  130.                                 'de-DE' => 'Die Warengruppe (Rabattgruppe) kann über das ACRIS Plugin verwendet werden, um allen Produkten mit derselben Warengruppe (Rabattgruppe) einen Rabatt zu ermöglichen.'
  131.                             ]
  132.                         ]]
  133.                 ],
  134.                 'relations' => [
  135.                     [
  136.                         'entityName' => 'product'
  137.                     ]
  138.                 ]
  139.             ]], $context);
  140.         };
  141.     }
  142.     private function removeCustomFields(Context $context, array $setNames): void
  143.     {
  144.         /* Check for snippets if they exist for custom fields */
  145.         $this->checkForExistingCustomFieldSnippets($context);
  146.         $customFieldSet $this->container->get('custom_field_set.repository');
  147.         foreach ($setNames as $setName) {
  148.             $id $customFieldSet->searchIds((new Criteria())->addFilter(new EqualsFilter('name'$setName)), $context)->firstId();
  149.             if($id$customFieldSet->delete([['id' => $id]], $context);
  150.         }
  151.     }
  152.     private function checkForExistingCustomFieldSnippets(Context $context)
  153.     {
  154.         /** @var EntityRepositoryInterface $snippetRepository */
  155.         $snippetRepository $this->container->get('snippet.repository');
  156.         $criteria = new Criteria();
  157.         $criteria->addFilter(new MultiFilter(MultiFilter::CONNECTION_OR, [
  158.             new EqualsFilter('translationKey''customFields.' 'acris_discount_group_value'),
  159.             new EqualsFilter('translationKey''customFields.' 'acris_discount_group_customer_value'),
  160.             new EqualsFilter('translationKey''customFields.' 'acris_discount_group_product_value'),
  161.         ]));
  162.         /** @var EntitySearchResult $searchResult */
  163.         $searchResult $snippetRepository->search($criteria$context);
  164.         if ($searchResult->count() > 0) {
  165.             $snippetIds = [];
  166.             /** @var SnippetEntity $snippet */
  167.             foreach ($searchResult->getEntities()->getElements() as $snippet) {
  168.                 $snippetIds[] = [
  169.                     'id' => $snippet->getId()
  170.                 ];
  171.             }
  172.             if (!empty($snippetIds)) {
  173.                 $snippetRepository->delete($snippetIds$context);
  174.             }
  175.         }
  176.     }
  177.     private function addImportExportProfile(Context $context): void
  178.     {
  179.         $importExportProfileRepository $this->container->get('import_export_profile.repository');
  180.         foreach ($this->getOptimizedSystemDefaultProfiles() as $profile) {
  181.             $this->createIfNotExists($importExportProfileRepository, [['name' => 'name''value' => $profile['name']]], $profile$context);
  182.         }
  183.     }
  184.     private function getOptimizedSystemDefaultProfiles(): array
  185.     {
  186.         return [
  187.             [
  188.                 'name' => self::IMPORT_EXPORT_PROFILE_NAME,
  189.                 'label' => self::IMPORT_EXPORT_PROFILE_NAME,
  190.                 'systemDefault' => true,
  191.                 'sourceEntity' => 'acris_discount_group',
  192.                 'fileType' => 'text/csv',
  193.                 'delimiter' => ';',
  194.                 'enclosure' => '"',
  195.                 'mapping' => [
  196.                     ['key' => 'id''mappedKey' => 'id'],
  197.                     ['key' => 'internalName''mappedKey' => 'internalName'],
  198.                     ['key' => 'active''mappedKey' => 'active'],
  199.                     ['key' => 'activeFrom''mappedKey' => 'activeFrom'],
  200.                     ['key' => 'activeUntil''mappedKey' => 'activeUntil'],
  201.                     ['key' => 'priority''mappedKey' => 'priority'],
  202.                     ['key' => 'excluded''mappedKey' => 'excluded'],
  203.                     ['key' => 'customerAssignmentType''mappedKey' => 'customerAssignmentType'],
  204.                     ['key' => 'customer.id''mappedKey' => 'customerId'],
  205.                     ['key' => 'discountGroup''mappedKey' => 'categoryDiscountGroup'],
  206.                     ['key' => 'rules''mappedKey' => 'ruleIds'],
  207.                     ['key' => 'productAssignmentType''mappedKey' => 'productAssignmentType'],
  208.                     ['key' => 'product.id''mappedKey' => 'productId'],
  209.                     ['key' => 'materialGroup''mappedKey' => 'productDiscountGroup'],
  210.                     ['key' => 'productStreams''mappedKey' => 'productStreamIds'],
  211.                     ['key' => 'discountType''mappedKey' => 'discountType'],
  212.                     ['key' => 'discount''mappedKey' => 'discount'],
  213.                     ['key' => 'calculationType''mappedKey' => 'calculationType'],
  214.                     ['key' => 'listPriceType''mappedKey' => 'listPriceType'],
  215.                 ],
  216.                 'translations' => [
  217.                     'en-GB' => [
  218.                         'label' => self::IMPORT_EXPORT_PROFILE_NAME
  219.                     ],
  220.                     'de-DE' => [
  221.                         'label' => self::IMPORT_EXPORT_PROFILE_NAME
  222.                     ]
  223.                 ],
  224.             ],
  225.         ];
  226.     }
  227.     private function createIfNotExists(EntityRepositoryInterface $repository, array $equalFields, array $dataContext $context)
  228.     {
  229.         $filters = [];
  230.         foreach ($equalFields as $equalField) {
  231.             $filters[] = new EqualsFilter($equalField['name'], $equalField['value']);
  232.         }
  233.         if(sizeof($filters) > 1) {
  234.             $filter = new MultiFilter(MultiFilter::CONNECTION_OR$filters);
  235.         } else {
  236.             $filter array_shift($filters);
  237.         }
  238.         $searchResult $repository->search((new Criteria())->addFilter($filter), $context);
  239.         if($searchResult->count() == 0) {
  240.             $repository->create([$data], $context);
  241.         }
  242.     }
  243.     private function cleanupImportExportProfile(Context $context): void
  244.     {
  245.         $importExportProfile $this->container->get('import_export_profile.repository');
  246.         $storeLocatorProfiles $importExportProfile->search((new Criteria())->addFilter(new EqualsFilter('sourceEntity''acris_discount_group')), $context);
  247.         $ids = [];
  248.         if ($storeLocatorProfiles->getTotal() > && $storeLocatorProfiles->first()) {
  249.             /** @var ImportExportProfileEntity $entity */
  250.             foreach ($storeLocatorProfiles->getEntities() as $entity) {
  251.                 if ($entity->getSystemDefault() === true) {
  252.                     $importExportProfile->update([
  253.                         ['id' => $entity->getId(), 'systemDefault' => false ]
  254.                     ], $context);
  255.                 }
  256.                 $ids[] = ['id' => $entity->getId()];
  257.             }
  258.             $importExportProfile->delete($ids$context);
  259.         }
  260.     }
  261.     private function insertDefaultMailTemplate(Context $context): void
  262.     {
  263.         $mailTemplateTypeRepository $this->container->get('mail_template_type.repository');
  264.         $mailTemplateTypePartialDeliverySearchResult $mailTemplateTypeRepository->searchIds((new Criteria())->addFilter(new EqualsFilter('technicalName'self::DEFAULT_MAIL_TEMPLATE_TYPE_DISCOUNT_GROUP)), $context);
  265.         if(empty($mailTemplateTypePartialDeliverySearchResult->firstId())) {
  266.             $mailTemplateTypePartialDeliveryId Uuid::randomHex();
  267.             $mailTemplatePartialDeliveryId Uuid::randomHex();
  268.             $mailTemplateTypePartialDeliveryData = [
  269.                 'id' => $mailTemplateTypePartialDeliveryId,
  270.                 'technicalName' => self::DEFAULT_MAIL_TEMPLATE_TYPE_DISCOUNT_GROUP,
  271.                 'availableEntities' => [ "order" => "order""salesChannel" =>"sales_channel""editOrderUrl" =>null ],
  272.                 'translations' => [
  273.                     'de-DE' => [
  274.                         'name' => 'ACRIS-Auftragsbestätigung mit Rabatten aus der Rabattgruppe'
  275.                     ],
  276.                     'en-GB' => [
  277.                         'name' => 'ACRIS order confirmation with discounts from discount group'
  278.                     ],
  279.                     [
  280.                         'name' => 'ACRIS order confirmation with discounts from discount group',
  281.                         'languageId' => Defaults::LANGUAGE_SYSTEM
  282.                     ]
  283.                 ],
  284.                 'mailTemplates' => [
  285.                     [
  286.                         'id' => $mailTemplatePartialDeliveryId,
  287.                         'systemDefault' => true,
  288.                         'translations' => [
  289.                             'de-DE' => [
  290.                                 'senderName' => '{{ salesChannel.name }}',
  291.                                 'subject' => 'Auftragsbestätigung - Rabattgruppe',
  292.                                 'description' => 'Standard-E-Mail-Vorlage für Rabattgruppen.',
  293.                                 'contentHtml' => file_get_contents($this->path '/Resources/mail-template/html/de-DE/discount-group.html.twig'),
  294.                                 'contentPlain' => 'Kein Inhalt.'
  295.                             ],
  296.                             'en-GB' => [
  297.                                 'senderName' => '{{ salesChannel.name }}',
  298.                                 'subject' => 'Order confirmation - Discount group',
  299.                                 'description' => 'Default E-mail template for discount groups.',
  300.                                 'contentHtml' => file_get_contents($this->path '/Resources/mail-template/html/en-GB/discount-group.html.twig'),
  301.                                 'contentPlain' => 'No content.'
  302.                             ],
  303.                             [
  304.                                 'senderName' => '{{ salesChannel.name }}',
  305.                                 'subject' => 'Order confirmation - Discount group',
  306.                                 'description' => 'Default E-mail template for discount groups.',
  307.                                 'contentHtml' => file_get_contents($this->path '/Resources/mail-template/html/en-GB/discount-group.html.twig'),
  308.                                 'contentPlain' => 'No content.',
  309.                                 'languageId' => Defaults::LANGUAGE_SYSTEM
  310.                             ]
  311.                         ],
  312.                     ]
  313.                 ]
  314.             ];
  315.             $mailTemplateTypeRepository->upsert([$mailTemplateTypePartialDeliveryData], $context);
  316.         }
  317.     }
  318.     private function removeDefaultMailTemplate(Context $context): void
  319.     {
  320.         $mailTemplateTypeRepository $this->container->get('mail_template_type.repository');
  321.         $mailTemplateTypePartialDeliverySearchResult $mailTemplateTypeRepository->searchIds((new Criteria())->addFilter(new EqualsFilter('technicalName'self::DEFAULT_MAIL_TEMPLATE_TYPE_DISCOUNT_GROUP)), $context);
  322.         if($mailTemplateTypePartialDeliverySearchResult->firstId()) {
  323.             $mailTemplateRepository $this->container->get('mail_template.repository');
  324.             $mailTemplateSearchResult $mailTemplateRepository->searchIds((new Criteria())->addFilter(new EqualsFilter('mailTemplateTypeId'$mailTemplateTypePartialDeliverySearchResult->firstId())), $context);
  325.             $templateAssigned false;
  326.             foreach ($mailTemplateSearchResult->getIds() as $id) {
  327.                 $eventActionRepository $this->container->get('event_action.repository');
  328.                 $eventActionSearchResult $eventActionRepository->searchIds((new Criteria())->addFilter(new EqualsFilter('config.mail_template_id'$id)), $context);
  329.                 if($eventActionSearchResult->firstId() && $eventActionSearchResult->getTotal() > 0$templateAssigned true;
  330.             }
  331.             if ($templateAssigned !== true) {
  332.                 foreach ($mailTemplateSearchResult->getIds() as $id) {
  333.                     $mailTemplateRepository->delete([['id'=>$id]], $context);
  334.                 }
  335.                 $mailTemplateTypeRepository->delete([['id'=>$mailTemplateTypePartialDeliverySearchResult->firstId()]], $context);
  336.             }
  337.         }
  338.     }
  339. }