<?php
declare(strict_types=1);
namespace BitBag\OpenMarketplace\Component\Elasticsearch\Controller;
use BitBag\OpenMarketplace\Component\Elasticsearch\Provider\RedirectResponseProviderInterface;
use BitBag\OpenMarketplace\Component\Taxonomy\Entity\TaxonInterface;
use BitBag\SyliusElasticsearchPlugin\Controller\RequestDataHandler\DataHandlerInterface;
use BitBag\SyliusElasticsearchPlugin\Controller\RequestDataHandler\PaginationDataHandlerInterface;
use BitBag\SyliusElasticsearchPlugin\Controller\RequestDataHandler\SortDataHandlerInterface;
use BitBag\SyliusElasticsearchPlugin\Finder\ShopProductsFinderInterface;
use BitBag\SyliusElasticsearchPlugin\Form\Type\ShopProductsFilterType;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Twig\Environment;
final class ListProductsAction
{
private static iterable $currentPageProducts;
private static TaxonInterface $taxon;
public function __construct(
private FormFactoryInterface $formFactory,
private DataHandlerInterface $shopProductListDataHandler,
private SortDataHandlerInterface $shopProductsSortDataHandler,
private PaginationDataHandlerInterface $paginationDataHandler,
private ShopProductsFinderInterface $shopProductsFinder,
private Environment $twig,
private RedirectResponseProviderInterface $redirectResponseProvider
) {
}
public function __invoke(Request $request): Response
{
$redirectResponse = $this->redirectResponseProvider->provide($request, [
'slug' => $request->get('slug'),
]);
if (null !== $redirectResponse) {
return $redirectResponse;
}
$form = $this->formFactory->create(ShopProductsFilterType::class);
$form->handleRequest($request);
$requestData = array_merge(
$form->getData(),
$request->query->all(),
['slug' => $request->get('slug')]
);
if (!$form->isValid()) {
$requestData = $this->clearInvalidEntries($form, $requestData);
}
$data = array_merge(
$this->shopProductListDataHandler->retrieveData($requestData),
$this->shopProductsSortDataHandler->retrieveData($requestData),
$this->paginationDataHandler->retrieveData($requestData)
);
$template = $request->get('template');
$products = $this->shopProductsFinder->find($data);
self::$currentPageProducts = $products->getCurrentPageResults();
self::$taxon = $data['taxon'];
return new Response($this->twig->render($template, [
'form' => $form->createView(),
'products' => $products,
'taxon' => $data['taxon'],
]));
}
private function clearInvalidEntries(FormInterface $form, array $requestData): array
{
/** @var FormError $error */
foreach ($form->getErrors(true) as $error) {
$errorOrigin = $error->getOrigin();
if (null === $errorOrigin) {
continue;
}
$parent = $errorOrigin->getParent();
if (null === $parent) {
continue;
}
$path = ($parent->getPropertyPath() ?? '') . $errorOrigin->getPropertyPath();
$keys = explode('][', trim($path, '[]'));
$dataRef = &$requestData;
foreach ($keys as $index => $key) {
if (isset($dataRef[$key])) {
if ($index === count($keys) - 1) {
unset($dataRef[$key]);
} else {
$dataRef = &$dataRef[$key];
}
}
}
}
return $requestData;
}
public static function getCurrentPageProducts(): iterable
{
return self::$currentPageProducts;
}
public static function getTaxon(): TaxonInterface
{
return self::$taxon;
}
}