src/Controller/ECommerce/App/ProductController.php line 44

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Controller\ECommerce\App;
  4. use App\Controller\ControllerTrait;
  5. use App\DTO\ECommerce\ProductFilterBySizeDTO;
  6. use App\Entity\ECommerce\Product;
  7. use App\Form\ECommerce\Filter\ProductFilterByCategory;
  8. use App\Form\ECommerce\Filter\ProductFilterByName;
  9. use App\Form\ECommerce\Filter\ProductFilterBySize;
  10. use App\Form\ECommerce\Filter\ProductFilterType;
  11. use App\Form\ECommerce\Filter\ProductSortType;
  12. use App\Helper\CacheHelper;
  13. use App\Model\ECommerce\Index;
  14. use App\Repository\ECommerce\ProductCategoryRepository;
  15. use App\Service\ECommerce\ProductTwigExtension;
  16. use DateTime;
  17. use Doctrine\Common\Collections\Collection;
  18. use Doctrine\ORM\EntityManagerInterface;
  19. use Knp\Component\Pager\PaginatorInterface;
  20. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
  21. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  22. use Symfony\Component\HttpFoundation\Request;
  23. use Symfony\Component\HttpFoundation\RequestStack;
  24. use Symfony\Component\HttpFoundation\Response;
  25. use Symfony\Component\Routing\Annotation\Route;
  26. #[Route('/{_locale}/product', requirements: ['_locale' => '\w{2}'])]
  27. class ProductController extends AbstractController
  28. {
  29. const INDEX_ROUTE = 'mdl_app_product_index';
  30. use ControllerTrait;
  31. #[Route('/index', name: 'mdl_app_product_index')]
  32. #[Cache(maxage: 2592000, smaxage: 2592000, public: true)]
  33. public function indexAction(
  34. Request $request,
  35. PaginatorInterface $paginator,
  36. ProductTwigExtension $productTwigExtension,
  37. EntityManagerInterface $entityManager
  38. ): Response {
  39. $form = $this->createForm(ProductFilterType::class)->handleRequest($request);
  40. $formData = $form->getData();
  41. $filters = $form->isSubmitted() && $form->isValid()
  42. ? $formData
  43. : [];
  44. $user = $this->getUser();
  45. $reverseRate = $productTwigExtension->currencyReverseRateFunction($user);
  46. if (!empty($filters['min'])) {
  47. $filters['min'] /= $reverseRate;
  48. }
  49. if (!empty($filters['max'])) {
  50. $filters['max'] /= $reverseRate;
  51. }
  52. $isLargeView = $request->query->get('view') === 'large-icons';
  53. $products = $paginator->paginate(
  54. $entityManager->getRepository(Product::class)->findAllInStockWithFilter($filters),
  55. $request->query->getInt('page', 1),
  56. $request->query->getInt('limit', $isLargeView ? 8 : 6)
  57. );
  58. return $this->render(
  59. $this->isFragment($request)
  60. ? 'ECommerce/App/Product/index.ajax.twig'
  61. : ($isLargeView ? 'ECommerce/App/Product/large_icons.html.twig' : 'ECommerce/App/Product/index.html.twig'),
  62. [
  63. 'products' => $products,
  64. 'form' => $form->createView(),
  65. ]
  66. );
  67. }
  68. #[Route('/{id}', name: 'mdl_app_product_show', requirements: ['id' => '\d+'], methods: ['GET'])]
  69. #[Cache(maxage: 2592000, smaxage: 2592000, public: true)]
  70. public function showAction(Product $product): Response
  71. {
  72. $breadcrumbs = [
  73. ['label' => 'product.index', 'url' => $this->generateUrl('public_index_localized')],
  74. ['label' => 'product.shop', 'url' => $this->generateUrl('mdl_app_product_index')],
  75. [
  76. 'label' => $product->getCategory()->translate()->getName(),
  77. 'url' => $this->generateUrl('mdl_app_product_index',
  78. ['categories' => [$product->getCategory()->getId()]]
  79. )
  80. ],
  81. ];
  82. if ($product->getSubCategory() instanceof \App\Entity\ECommerce\ProductSubCategory) {
  83. $breadcrumbs[] = [
  84. 'label' => $product->getSubCategory()->getName(),
  85. 'url' => $this->generateUrl(
  86. 'mdl_app_product_index',
  87. ['subCategories' => [$product->getSubCategory()?->getId()]]
  88. )
  89. ];
  90. }
  91. $breadcrumbs[] = ['label' => $product->getTitle()];
  92. return $this->render('ECommerce/App/Product/show.html.twig', [
  93. 'product' => $product,
  94. 'breadcrumbs' => $breadcrumbs,
  95. ]);
  96. }
  97. #[Route('/remote/{remoteId}', name: 'mdl_app_remote_product_show', requirements: ['remoteId' => '\d+'], methods: ['GET'])]
  98. #[Cache(maxage: 2592000, smaxage: 2592000, public: true)]
  99. public function showByRemoteId(Product $product): Response
  100. {
  101. return $this->render('ECommerce/App/Product/show.html.twig', ['product' => $product]);
  102. }
  103. #[Route('/filter', name: 'mdl_app_product_filter', methods: ['GET'])]
  104. #[Cache(maxage: 2592000, smaxage: 2592000, public: true)]
  105. public function filterAction(
  106. Request $request,
  107. PaginatorInterface $paginator,
  108. CacheHelper $cacheHelper,
  109. EntityManagerInterface $entityManager,
  110. RequestStack $requestStack
  111. ): Response {
  112. $masterRequest = $requestStack->getMainRequest();
  113. $form = $this->createForm(ProductFilterBySize::class, null, [
  114. 'action' => $this->generateUrl('mdl_app_product_filter'),
  115. 'method' => 'GET'
  116. ])->handleRequest($masterRequest);
  117. if ($this->isFragment($request)) {
  118. return $cacheHelper::responseCached(
  119. $this->render('ECommerce/App/Product/filter.form.twig', [
  120. 'form' => $form->createView(),
  121. ])
  122. );
  123. }
  124. $sort = $request->query->get('sortBy') ?: '';
  125. $sortForm = $this->createForm(ProductSortType::class, null, [
  126. 'sortBy' => $sort,
  127. 'action' => $this->generateUrl('mdl_app_product_filter'),
  128. 'method' => 'GET',
  129. ])->handleRequest($request);
  130. /** @var ProductFilterBySizeDTO $data */
  131. $data = $form->getNormData();
  132. $productsQuery = $entityManager->getRepository(Product::class)->createBySizeQuery($data, $sort);
  133. $products = $paginator->paginate(
  134. $productsQuery,
  135. (int) $request->get('page', 1),
  136. (int) $request->get('itemsPerPage', 20)
  137. );
  138. $responseData = [
  139. 'form' => $form->createView(),
  140. 'sortForm' => $sortForm->createView(),
  141. 'products' => $products,
  142. 'title' => $data->getTitle(),
  143. ];
  144. if ($request->isXmlHttpRequest() && $request->query->get('view') !== 'large-icons') {
  145. return $cacheHelper::responseCached(
  146. $this->render('ECommerce/App/Product/filter_by_name.ajax.twig', $responseData)
  147. );
  148. }
  149. if ($request->isXmlHttpRequest()) {
  150. return $cacheHelper::responseCached(
  151. $this->render('ECommerce/App/Product/large_icons.ajax.twig', $responseData)
  152. );
  153. }
  154. $responseData['sortForm'] = $this->createForm(ProductSortType::class, null, [
  155. 'action' => $this->generateUrl('mdl_app_product_filter'),
  156. 'method' => 'GET'
  157. ])->handleRequest($masterRequest)->createView();
  158. return $cacheHelper::responseCached(
  159. $this->render('ECommerce/App/Product/filter.html.twig', $responseData)
  160. );
  161. }
  162. #[Route('/filter_by_name', name: 'mdl_app_product_filter_by_name')]
  163. #[Cache(maxage: 2592000, smaxage: 2592000, public: true)]
  164. public function filterByNameAction(
  165. Request $request,
  166. PaginatorInterface $paginator,
  167. CacheHelper $cacheHelper,
  168. RequestStack $requestStack
  169. ): Response {
  170. $searchTitle = $requestStack->getMainRequest()->get('title', '');
  171. preg_match('/^\*.*/', (string) $searchTitle, $minQuantity);
  172. $data = [
  173. 'title' => $searchTitle
  174. ];
  175. $form = $this->createForm(ProductFilterByName::class, $data, [
  176. 'action' => $this->generateUrl('mdl_app_product_filter_by_name'),
  177. 'method' => 'GET'
  178. ])->handleRequest($request);
  179. $title = ltrim(Index::index($form->getNormData()['title']), '*');
  180. $minQuantity = (int)(count($minQuantity) < 1);
  181. $responseData = [
  182. 'form' => $form->createView(),
  183. 'products' => $paginator->paginate(
  184. [],
  185. (int) $request->get('page', 1),
  186. (int) $request->get('itemsPerPage', 20)
  187. ),
  188. 'title' => $searchTitle,
  189. 'initialTitle' => $title,
  190. ];
  191. if ($this->isFragment($request)) {
  192. return $cacheHelper::responseCached(
  193. $this->render('ECommerce/App/Product/filter_by_name.form.twig', $responseData)
  194. ->setExpires(new DateTime('+2 days'))
  195. );
  196. }
  197. if (!$form->isSubmitted() || !$form->isValid()) {
  198. return $cacheHelper::responseCached(
  199. $this->render('ECommerce/App/Product/filter.html.twig', $responseData)
  200. ->setExpires(new DateTime('+2 days'))
  201. );
  202. }
  203. $responseData['products'] = $paginator->paginate(
  204. $this->getDoctrine()
  205. ->getRepository(Product::class)
  206. ->createLikeSearchTitleQueryBuilder($title, $minQuantity),
  207. $request->query->getInt('page', 1),
  208. $request->query->getInt('itemsPerPage', 20)
  209. );
  210. if ($request->isXmlHttpRequest() && $request->query->get('view') !== 'largeIcons') {
  211. return $cacheHelper::responseCached(
  212. $this->render('ECommerce/App/Product/filter_by_name.ajax.twig', $responseData)
  213. ->setExpires(new DateTime('+2 days'))
  214. );
  215. }
  216. return $cacheHelper::responseCached(
  217. $this->render('ECommerce/App/Product/filter.html.twig', $responseData)
  218. ->setExpires(new DateTime('+2 days'))
  219. );
  220. }
  221. #[Route('/filter_by_category', name: 'mdl_app_product_filter_by_category')]
  222. #[Cache(maxage: 2592000, smaxage: 2592000, public: true)]
  223. public function filterByCategoryAction(
  224. // Request $request,
  225. // PaginatorInterface $paginator,
  226. // CacheHelper $cacheHelper,
  227. // RequestStack $requestStack,
  228. // ProductCategoryRepository $categoryRepository
  229. ): Response {
  230. return new Response();
  231. // $category = $requestStack->getMainRequest()->get('category');
  232. // $data = array(
  233. // 'category' => !empty($category) ? $categoryRepository->find($category) : null,
  234. // );
  235. //
  236. // $form = $this->createForm(ProductFilterByCategory::class, $data, array(
  237. // 'action' => $this->generateUrl('mdl_app_product_filter_by_category'),
  238. // 'method' => 'GET',
  239. // ))->handleRequest($request);
  240. //
  241. // if ($this->isFragment($request)) {
  242. // return $cacheHelper::responseCached(
  243. // $this->render('ECommerce/App/Product/filter_by_category.form.twig', array(
  244. // 'categoryForm' => $form->createView(),
  245. // ))
  246. // );
  247. // }
  248. //
  249. // if (!$form->isSubmitted() || !$form->isValid()) {
  250. // return $cacheHelper::responseCached(
  251. // $this->render('ECommerce/App/Product/filter_by_category.html.twig', [
  252. // 'categoryForm' => $form->createView(),
  253. // 'products' => $responseData['products'] = $paginator->paginate(
  254. // [],
  255. // (int) $request->get('page', 1),
  256. // (int) $request->get('itemsPerPage', 20)
  257. // ),
  258. // 'title' => null,
  259. // ])
  260. // );
  261. // }
  262. //
  263. // $response = array(
  264. // 'categoryForm' => $form->createView(),
  265. // 'products' => $responseData['products'] = $paginator->paginate(
  266. // $this->getDoctrine()->getRepository(Product::class)->createByCategoryQueryBuilder($form->getNormData()['category']),
  267. // (int) $request->get('page', 1),
  268. // (int) $request->get('itemsPerPage', 20)
  269. // ),
  270. // 'title' => null,
  271. // );
  272. //
  273. // if ($request->isXmlHttpRequest()) {
  274. // return $cacheHelper::responseCached(
  275. // $this->render('ECommerce/App/Product/filter_by_category.ajax.twig', $response)
  276. // );
  277. // }
  278. //
  279. // return $cacheHelper::responseCached(
  280. // $this->render('ECommerce/App/Product/filter_by_category.html.twig', $response)
  281. // );
  282. }
  283. }