src/Component/Elasticsearch/Controller/ListProductsAction.php line 54

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace BitBag\OpenMarketplace\Component\Elasticsearch\Controller;
  4. use BitBag\OpenMarketplace\Component\Elasticsearch\Provider\RedirectResponseProviderInterface;
  5. use BitBag\OpenMarketplace\Component\Organization\Checker\OrganizationStatusCheckerInterface;
  6. use BitBag\OpenMarketplace\Component\Organization\Entity\OrganizationInterface;
  7. use BitBag\OpenMarketplace\Component\Product\Entity\ProductInterface;
  8. use BitBag\OpenMarketplace\Component\Taxonomy\Entity\TaxonInterface;
  9. use BitBag\OpenMarketplace\Component\Vendor\Entity\VendorInterface;
  10. use BitBag\SyliusElasticsearchPlugin\Controller\RequestDataHandler\DataHandlerInterface;
  11. use BitBag\SyliusElasticsearchPlugin\Controller\RequestDataHandler\PaginationDataHandlerInterface;
  12. use BitBag\SyliusElasticsearchPlugin\Controller\RequestDataHandler\SortDataHandlerInterface;
  13. use BitBag\SyliusElasticsearchPlugin\Finder\ShopProductsFinderInterface;
  14. use BitBag\SyliusElasticsearchPlugin\Form\Type\ShopProductsFilterType;
  15. use Symfony\Component\Form\FormError;
  16. use Symfony\Component\Form\FormFactoryInterface;
  17. use Symfony\Component\Form\FormInterface;
  18. use Symfony\Component\HttpFoundation\Request;
  19. use Symfony\Component\HttpFoundation\Response;
  20. use Twig\Environment;
  21. final class ListProductsAction
  22. {
  23.     private static iterable $currentPageProducts;
  24.     private static TaxonInterface $taxon;
  25.     public function __construct(
  26.         private FormFactoryInterface $formFactory,
  27.         private DataHandlerInterface $shopProductListDataHandler,
  28.         private SortDataHandlerInterface $shopProductsSortDataHandler,
  29.         private PaginationDataHandlerInterface $paginationDataHandler,
  30.         private ShopProductsFinderInterface $shopProductsFinder,
  31.         private Environment $twig,
  32.         private RedirectResponseProviderInterface $redirectResponseProvider,
  33.         private OrganizationStatusCheckerInterface $organizationStatusChecker,
  34.         ) {
  35.     }
  36.     public function __invoke(Request $request): Response
  37.     {
  38.         $redirectResponse $this->redirectResponseProvider->provide($request, [
  39.             'slug' => $request->get('slug'),
  40.         ]);
  41.         if (null !== $redirectResponse) {
  42.             return $redirectResponse;
  43.         }
  44.         $form $this->formFactory->create(ShopProductsFilterType::class);
  45.         $form->handleRequest($request);
  46.         $requestData array_merge(
  47.             $form->getData(),
  48.             $request->query->all(),
  49.             ['slug' => $request->get('slug')]
  50.         );
  51.         if (!$form->isValid()) {
  52.             $requestData $this->clearInvalidEntries($form$requestData);
  53.         }
  54.         $data array_merge(
  55.             $this->shopProductListDataHandler->retrieveData($requestData),
  56.             $this->shopProductsSortDataHandler->retrieveData($requestData),
  57.             $this->paginationDataHandler->retrieveData($requestData)
  58.         );
  59.         $template $request->get('template');
  60.         $products $this->shopProductsFinder->find($data);
  61.         self::$currentPageProducts $this->normalizeCurrentPageProducts($products->getCurrentPageResults());
  62.         $this->organizationStatusChecker->preload($this->extractOrganizations(self::$currentPageProducts));
  63.         self::$taxon $data['taxon'];
  64.         return new Response($this->twig->render($template, [
  65.             'form' => $form->createView(),
  66.             'products' => $products,
  67.             'taxon' => $data['taxon'],
  68.         ]));
  69.     }
  70.     private function clearInvalidEntries(FormInterface $form, array $requestData): array
  71.     {
  72.         foreach ($form->getErrors(true) as $error) {
  73.             if (!$error instanceof FormError) {
  74.                 continue;
  75.             }
  76.             $errorOrigin $error->getOrigin();
  77.             if (null === $errorOrigin) {
  78.                 continue;
  79.             }
  80.             $parent $errorOrigin->getParent();
  81.             if (null === $parent) {
  82.                 continue;
  83.             }
  84.             $path = ($parent->getPropertyPath() ?? '') . $errorOrigin->getPropertyPath();
  85.             $keys explode(']['trim($path'[]'));
  86.             $dataRef = &$requestData;
  87.             foreach ($keys as $index => $key) {
  88.                 if (isset($dataRef[$key])) {
  89.                     if ($index === count($keys) - 1) {
  90.                         unset($dataRef[$key]);
  91.                     } else {
  92.                         $dataRef = &$dataRef[$key];
  93.                     }
  94.                 }
  95.             }
  96.         }
  97.         return $requestData;
  98.     }
  99.     public static function getCurrentPageProducts(): iterable
  100.     {
  101.         return self::$currentPageProducts;
  102.     }
  103.     public static function getTaxon(): TaxonInterface
  104.     {
  105.         return self::$taxon;
  106.     }
  107.     private function normalizeCurrentPageProducts(iterable $products): array
  108.     {
  109.         if (is_array($products)) {
  110.             return $products;
  111.         }
  112.         return iterator_to_array($productsfalse);
  113.     }
  114.     private function extractOrganizations(array $products): array
  115.     {
  116.         $organizations = [];
  117.         foreach ($products as $product) {
  118.             if (!$product instanceof ProductInterface) {
  119.                 continue;
  120.             }
  121.             $vendor $product->getVendor();
  122.             if (!$vendor instanceof VendorInterface) {
  123.                 continue;
  124.             }
  125.             $organization $vendor->getOrganization();
  126.             if (!$organization instanceof OrganizationInterface) {
  127.                 continue;
  128.             }
  129.             $organizationId $organization->getId();
  130.             $cacheKey null !== $organizationId ? (string) $organizationId : (string) spl_object_id($organization);
  131.             $organizations[$cacheKey] = $organization;
  132.         }
  133.         return array_values($organizations);
  134.     }
  135. }