custom/static-plugins/CioItpThemeFilters/src/Subscriber/CioItpThemeFiltersSubscriber.php line 47

Open in your IDE?
  1. <?php
  2. namespace CioItpThemeFilters\Subscriber;
  3. use CioItpThemeFilters\CioItpThemeFilters;
  4. use Shopware\Administration\Framework\Routing\AdministrationRouteScope;
  5. use Shopware\Core\Content\Category\CategoryEvents;
  6. use Shopware\Core\Content\Product\Events\ProductListingCollectFilterEvent;
  7. use Shopware\Core\Content\Product\SalesChannel\Listing\Filter;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\AndFilter;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\RangeFilter;
  11. use Shopware\Core\Framework\Routing\Annotation\RouteScope;
  12. use Shopware\Storefront\Event\StorefrontRenderEvent;
  13. use Shopware\Storefront\Framework\Routing\StorefrontRouteScope;
  14. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  15. use Symfony\Component\HttpKernel\Event\ResponseEvent;
  16. use Symfony\Component\HttpKernel\KernelEvents;
  17. class CioItpThemeFiltersSubscriber implements EventSubscriberInterface
  18. {
  19.     public const NUMBER_FILTERS = [
  20.         'itp_product_attributes_dk', 'itp_product_attributes_ml', 'itp_product_attributes_l'
  21.     ];
  22.     // CIO-AI-Driven: boolean listing filters (custom fields)
  23.     public const BOOLEAN_FILTERS = [
  24.         'itp_product_attributes_compatible_with_cnc',
  25.     ];
  26.     public function onProductListingCollectFilterEvent(ProductListingCollectFilterEvent $event): void
  27.     {
  28.         foreach (self::NUMBER_FILTERS as $filter) {
  29.             $this->newFilterNumber($event, $filter);
  30.         }
  31.         foreach (self::BOOLEAN_FILTERS as $filter) {
  32.             $this->newFilterBoolean($event, $filter);
  33.         }
  34.     }
  35.     private function newFilterNumber(ProductListingCollectFilterEvent $event, $name)
  36.     {
  37.         $filters = $event->getFilters();
  38.         $request = $event->getRequest();
  39.         $values = explode('-', $request->get($name));
  40.         $valueFrom = floatval($values[0]);
  41.         $valueTo = array_key_exists(1, $values) ? floatval($values[1]) : $valueFrom;
  42.         $filterFiltered = $valueFrom > 0.01;
  43.         $filter = new Filter(
  44.             $name,
  45.             $filterFiltered,
  46.             [],
  47.             new AndFilter(
  48.                 [
  49.                     new RangeFilter('customFields.' . $name, [RangeFilter::GTE => $valueFrom]),
  50.                     new RangeFilter('customFields.' . $name, [RangeFilter::LTE => $valueTo]),
  51.                 ]
  52.             ),
  53.             $valueFrom
  54.         );
  55.         $filters->add($filter);
  56.     }
  57.     private function newFilterBoolean(ProductListingCollectFilterEvent $event, string $name): void
  58.     {
  59.         $filters = $event->getFilters();
  60.         $request = $event->getRequest();
  61.         // checkbox sends e.g. "on" when checked
  62.         $isFiltered = (bool) $request->get($name);
  63.         $filter = new Filter(
  64.             $name,
  65.             $isFiltered,
  66.             [],
  67.             new EqualsFilter('customFields.' . $name, true),
  68.             $isFiltered
  69.         );
  70.         $filters->add($filter);
  71.     }
  72.     public function onKernelResponse(ResponseEvent $event): void
  73.     {
  74.         $request = $event->getRequest();
  75.         $response = $event->getResponse();
  76.         if ($request->getMethod() !== 'GET' || $request->isXmlHttpRequest()) {
  77.             return;
  78.         }
  79.         $scope = $request->attributes->get('_routeScope');
  80.         if (!($scope instanceof RouteScope)) {
  81.             return;
  82.         }
  83.         $scopes = $scope->getScopes();
  84.         if (empty($scopes) || !in_array(StorefrontRouteScope::ID, $scopes, true)) {
  85.             return;
  86.         }
  87.         $propertyId = $request->cookies->get(CioItpThemeFilters::FILTER_COOKIE_NAME);
  88.         if (!$propertyId) {
  89.             return;
  90.         }
  91.         $originalUri = $_SERVER['REQUEST_URI'];
  92.         $parsedUrl = parse_url($originalUri);
  93.         $path = $parsedUrl['path'] ?? '/';
  94.         parse_str($parsedUrl['query'] ?? '', $queryParams);
  95.         if (isset($queryParams['properties']) && str_contains($queryParams['properties'], $propertyId)) {
  96.             return;
  97.         }
  98.         if (!isset($queryParams['properties'])) {
  99.             $queryParams['properties'] = $propertyId;
  100.         } else {
  101.             $queryParams['properties'] .= "|$propertyId";
  102.         }
  103.         $newUrl = $path . '?' . http_build_query($queryParams);
  104.         $response->headers->set('Location', $newUrl);
  105.         $response->setStatusCode(302);
  106.     }
  107.     public static function getSubscribedEvents(): array
  108.     {
  109.         return [
  110.             ProductListingCollectFilterEvent::class => 'onProductListingCollectFilterEvent',
  111.             KernelEvents::RESPONSE => ['onKernelResponse', -11000]
  112.         ];
  113.     }
  114. }