vendor/store.shopware.com/acrisfiltercs/src/AcrisFilterCS.php line 23

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Acris\Filter;
  3. use Acris\Filter\Storefront\Subscriber\PropertyGroupSubscriber;
  4. use Doctrine\DBAL\Connection;
  5. use Shopware\Core\Content\Property\Aggregate\PropertyGroupOption\PropertyGroupOptionEntity;
  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\ContainsFilter;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
  13. use Shopware\Core\Framework\Plugin;
  14. use Shopware\Core\Framework\Plugin\Context\InstallContext;
  15. use Shopware\Core\Framework\Plugin\Context\ActivateContext;
  16. use Shopware\Core\Framework\Plugin\Context\UninstallContext;
  17. use Shopware\Core\Framework\Plugin\Context\UpdateContext;
  18. use Shopware\Core\System\CustomField\CustomFieldTypes;
  19. use Shopware\Core\System\Snippet\SnippetEntity;
  20. class AcrisFilterCS extends Plugin
  21. {
  22.     const DEFAULT_VALUE_OFFSET 0;
  23.     const DEFAULT_CRITERIA_LIMIT 50;
  24.     const CUSTOM_FIELD_SET_NAME_PRODUCT_FILTER 'acris_filter';
  25.     const CUSTOM_FIELD_SET_NAME_PROPERTY_FILTER 'acris_filter_property';
  26.     public function update(UpdateContext $updateContext): void
  27.     {
  28.         if ((version_compare($updateContext->getCurrentPluginVersion(), '1.1.0''<') && version_compare($updateContext->getUpdatePluginVersion(), '1.1.0''>='))) {
  29.             $this->removeCustomField('acris_filter_inactive'$updateContext->getContext());
  30.         }
  31.         if ((version_compare($updateContext->getCurrentPluginVersion(), '2.2.0''<') && version_compare($updateContext->getUpdatePluginVersion(), '2.2.0''>='))) {
  32.             if ($updateContext->getPlugin()->isActive()) {
  33.                 $this->insertDefaultValues($updateContext->getContext());
  34.             }
  35.         }
  36.     }
  37.     public function postUpdate(UpdateContext $updateContext): void
  38.     {
  39.         if (version_compare($updateContext->getCurrentPluginVersion(), '3.3.0''<') && version_compare($updateContext->getUpdatePluginVersion(), '1.4.1''>=') && $updateContext->getPlugin()->isActive() === true) {
  40.             $this->updateProperties($updateContext->getContext());
  41.         }
  42.     }
  43.     public function activate(ActivateContext $activateContext): void
  44.     {
  45.         $this->insertDefaultValues($activateContext->getContext());
  46.     }
  47.     public function uninstall(UninstallContext $context): void
  48.     {
  49.         if ($context->keepUserData()) {
  50.             return;
  51.         }
  52.         $this->cleanupDatabase();
  53.         $this->removeCustomFields($context->getContext(), [self::CUSTOM_FIELD_SET_NAME_PRODUCT_FILTER]);
  54.     }
  55.     public function install(InstallContext $context): void
  56.     {
  57.         $this->addCustomFields($context->getContext());
  58.     }
  59.     private function addCustomFields(Context $context): void
  60.     {
  61.         /* Check for snippets if they exist for custom fields */
  62.         $this->checkForExistingCustomFieldSnippets(['acris_filter_type''acris_filter_unit''acris_filter_hide'], $context);
  63.         $customFieldSet $this->container->get('custom_field_set.repository');
  64.         if ($customFieldSet->search((new Criteria())->addFilter(new EqualsFilter('name'self::CUSTOM_FIELD_SET_NAME_PRODUCT_FILTER)), $context)->count() == 0) {
  65.             $customFieldSet->create([[
  66.                 'name' => self::CUSTOM_FIELD_SET_NAME_PRODUCT_FILTER,
  67.                 'config' => [
  68.                     'label' => [
  69.                         'en-GB' => 'Product Filter',
  70.                         'de-DE' => 'Produkt Filter'
  71.                     ]
  72.                 ],
  73.                 'customFields' => [
  74.                     ['name' => 'acris_filter_type''type' => CustomFieldTypes::TEXT,
  75.                         'config' => [
  76.                             'componentName' => 'sw-field',
  77.                             'type' => 'text',
  78.                             'customFieldType' => 'text',
  79.                             'customFieldPosition' => 2,
  80.                             'label' => [
  81.                                 'en-GB' => 'Filter display type',
  82.                                 'de-DE' => 'Filter Darstellungsart'
  83.                             ]
  84.                         ]],
  85.                     ['name' => 'acris_filter_unit''type' => CustomFieldTypes::TEXT,
  86.                         'config' => [
  87.                             'componentName' => 'sw-field',
  88.                             'type' => 'text',
  89.                             'customFieldType' => 'text',
  90.                             'customFieldPosition' => 3,
  91.                             'label' => [
  92.                                 'en-GB' => 'Unit',
  93.                                 'de-DE' => 'Einheit',
  94.                             ]
  95.                         ]],
  96.                     ['name' => 'acris_filter_hide''type' => CustomFieldTypes::BOOL,
  97.                         'config' => [
  98.                             'componentName' => 'sw-field',
  99.                             'type' => 'checkbox',
  100.                             'customFieldType' => 'checkbox',
  101.                             'customFieldPosition' => 4,
  102.                             'label' => [
  103.                                 'en-GB' => 'Show filter only in dropdown',
  104.                                 'de-DE' => 'Filter nur in Dropdown anzeigen'
  105.                             ]
  106.                         ]],
  107.                 ],
  108.             ]], $context);
  109.         }
  110.         if ($customFieldSet->search((new Criteria())->addFilter(new EqualsFilter('name'self::CUSTOM_FIELD_SET_NAME_PROPERTY_FILTER)), $context)->count() == 0) {
  111.             $customFieldSet->create([[
  112.                 'name' => self::CUSTOM_FIELD_SET_NAME_PROPERTY_FILTER,
  113.                 'config' => [
  114.                     'label' => [
  115.                         'en-GB' => 'Property Filter',
  116.                         'de-DE' => 'Eigenschafts Filter'
  117.                     ]
  118.                 ],
  119.                 'customFields' => [
  120.                     ['name' => 'acris_filter_numeric''type' => CustomFieldTypes::FLOAT,
  121.                         'config' => [
  122.                             'componentName' => 'sw-field',
  123.                             'type' => 'number',
  124.                             'numberType' => 'float',
  125.                             'customFieldType' => 'number',
  126.                             'customFieldPosition' => 1,
  127.                             'label' => [
  128.                                 'en-GB' => 'Numerical value',
  129.                                 'de-DE' => 'Numerischer Wert'
  130.                             ]
  131.                         ]]
  132.                 ],
  133.             ]], $context);
  134.         }
  135.     }
  136.     private function removeCustomFields(Context $context, array $setNames): void
  137.     {
  138.         /* Check for snippets if they exist for custom fields */
  139.         $this->checkForExistingCustomFieldSnippets(['acris_filter_type''acris_filter_unit''acris_filter_hide'], $context);
  140.         $customFieldSet $this->container->get('custom_field_set.repository');
  141.         foreach ($setNames as $setName) {
  142.             $id $customFieldSet->searchIds((new Criteria())->addFilter(new EqualsFilter('name'$setName)), $context)->firstId();
  143.             if ($id$customFieldSet->delete([['id' => $id]], $context);
  144.         }
  145.     }
  146.     private function cleanupDatabase(): void
  147.     {
  148.         $connection $this->container->get(Connection::class);
  149.         $connection->executeUpdate('DROP TABLE IF EXISTS acris_filter');
  150.     }
  151.     public function insertDefaultValues(Context $context)
  152.     {
  153.         $filterRpository $this->container->get('acris_filter.repository');
  154.         $filters =
  155.             [[
  156.                 'identifier' => 'manufacturer',
  157.                 'active' => true,
  158.                 'position' => 1,
  159.                 'filter_type' => 'default',
  160.                 'hide' => false
  161.             ],
  162.                 [
  163.                     'identifier' => 'properties',
  164.                     'active' => true,
  165.                     'position' => 2,
  166.                     'filter_type' => 'default',
  167.                     'hide' => false
  168.                 ],
  169.                 [
  170.                     'identifier' => 'price',
  171.                     'active' => true,
  172.                     'position' => 3,
  173.                     'filter_type' => 'range_min_max',
  174.                     'hide' => false
  175.                 ],
  176.                 [
  177.                     'identifier' => 'rating',
  178.                     'active' => true,
  179.                     'position' => 4,
  180.                     'filter_type' => 'default',
  181.                     'hide' => false
  182.                 ],
  183.                 [
  184.                     'identifier' => 'shipping-free',
  185.                     'active' => true,
  186.                     'position' => 5,
  187.                     'filter_type' => 'default',
  188.                     'hide' => false
  189.                 ], [
  190.                 'identifier' => 'availability',
  191.                 'active' => true,
  192.                 'position' => 6,
  193.                 'filter_type' => 'default',
  194.                 'hide' => false
  195.             ], [
  196.                 'identifier' => 'categories',
  197.                 'active' => true,
  198.                 'position' => 0,
  199.                 'filter_type' => 'default',
  200.                 'hide' => false
  201.             ]];
  202.         foreach ($filters as $filter) {
  203.             $this->createIfNotExists($filterRpository, [['name' => 'identifier''value' => $filter['identifier']]], $filter$context);
  204.         }
  205.     }
  206.     private function createIfNotExists(EntityRepositoryInterface $repository, array $equalFields, array $dataContext $context)
  207.     {
  208.         $filters = [];
  209.         foreach ($equalFields as $equalField) {
  210.             $filters[] = new EqualsFilter($equalField['name'], $equalField['value']);
  211.         }
  212.         if (sizeof($filters) > 1) {
  213.             $filter = new MultiFilter(MultiFilter::CONNECTION_OR$filters);
  214.         } else {
  215.             $filter array_shift($filters);
  216.         }
  217.         $searchResult $repository->search((new Criteria())->addFilter($filter), $context);
  218.         if ($searchResult->count() == 0) {
  219.             $repository->create([$data], $context);
  220.         }
  221.     }
  222.     private function checkForExistingCustomFieldSnippets(array $customFieldsContext $context)
  223.     {
  224.         /** @var EntityRepositoryInterface $snippetRepository */
  225.         $snippetRepository $this->container->get('snippet.repository');
  226.         $criteria = new Criteria();
  227.         $filter = [];
  228.         foreach ($customFields as $customField) {
  229.             $filter[] = new EqualsFilter('translationKey''customFields.' $customField);
  230.         }
  231.         $criteria->addFilter(new MultiFilter(MultiFilter::CONNECTION_OR$filter));
  232.         /** @var EntitySearchResult $searchResult */
  233.         $searchResult $snippetRepository->search($criteria$context);
  234.         if ($searchResult->count() > 0) {
  235.             $snippetIds = [];
  236.             /** @var SnippetEntity $snippet */
  237.             foreach ($searchResult->getEntities()->getElements() as $snippet) {
  238.                 $snippetIds[] = [
  239.                     'id' => $snippet->getId()
  240.                 ];
  241.             }
  242.             if (!empty($snippetIds)) {
  243.                 $snippetRepository->delete($snippetIds$context);
  244.             }
  245.         }
  246.     }
  247.     private function removeCustomField(string $customFieldNameContext $context)
  248.     {
  249.         $this->checkForExistingCustomFieldSnippets([$customFieldName], $context);
  250.         $customFieldRepository $this->container->get('custom_field.repository');
  251.         $id $customFieldRepository->searchIds((new Criteria())->addFilter(new EqualsFilter('name'$customFieldName)), $context)->firstId();
  252.         if ($id) {
  253.             $customFieldRepository->delete([['id' => $id]], $context);
  254.         }
  255.     }
  256.     private function updateProperties(Context $context): void
  257.     {
  258.         $propertyGroupSubscriber $this->container->get(PropertyGroupSubscriber::class);
  259.         if (empty($propertyGroupSubscriber)) return;
  260.         /** @var EntityRepositoryInterface $propertyOptionRepository */
  261.         $propertyOptionRepository $this->container->get('property_group_option.repository');
  262.         $criteria = (new Criteria())
  263.             ->addFilter(
  264.                 new MultiFilter(MultiFilter::CONNECTION_OR, [
  265.                     new ContainsFilter('name'','),
  266.                     new ContainsFilter('name''.')
  267.                 ])
  268.             )->addAssociation('group');
  269.         $offset self::DEFAULT_VALUE_OFFSET;
  270.         $load true;
  271.         $updateData = [];
  272.         while ($load) {
  273.             $criteria->setOffset($offset);
  274.             $searchResult $propertyOptionRepository->search($criteria$context);
  275.             if ($searchResult->getTotal() > 0) {
  276.                 /** @var PropertyGroupOptionEntity $propertyOption */
  277.                 foreach ($searchResult->getEntities()->getElements() as $propertyOption) {
  278.                     $updateData array_merge($updateData$propertyGroupSubscriber->updatePropertyGroupAndOption($propertyOption->getGroup(), $propertyOption$context));
  279.                 }
  280.             }
  281.             $offset += self::DEFAULT_CRITERIA_LIMIT;
  282.             if ($searchResult->getTotal() < self::DEFAULT_CRITERIA_LIMIT$load false;
  283.         }
  284.         if (!empty($updateData)) {
  285.             $propertyOptionRepository->update($updateData$context);
  286.         }
  287.     }
  288. }