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

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\Entity\ECommerce\Product;
  6. use App\Entity\ECommerce\ProductCategory;
  7. use App\Form\ECommerce\Filter\ProductFilterByCategory;
  8. use App\Form\ECommerce\Filter\ProductFilterByName;
  9. use App\Form\ECommerce\Filter\ProductFilterBySize;
  10. use App\Helper\CacheHelper;
  11. use App\Model\ECommerce\Index;
  12. use App\Repository\ECommerce\ProductCategoryRepository;
  13. use DateTime;
  14. use Knp\Component\Pager\PaginatorInterface;
  15. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
  16. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  17. use Symfony\Component\HttpFoundation\Request;
  18. use Symfony\Component\HttpFoundation\RequestStack;
  19. use Symfony\Component\HttpFoundation\Response;
  20. use Symfony\Component\Routing\Annotation\Route;
  21. /**
  22. * Product controller.
  23. *
  24. * @package App\Controller\ECommerce\App
  25. *
  26. * @Route("/{_locale}/product", requirements={"_locale": "\w{2}"})
  27. */
  28. class ProductController extends AbstractController
  29. {
  30. const INDEX_ROUTE = 'mdl_app_product_index';
  31. use ControllerTrait;
  32. /**
  33. * Lists all product entities.
  34. *
  35. * @Route("/index", name="mdl_app_product_index")
  36. *
  37. * @Cache(expires="+2 days", public=true)
  38. *
  39. * @param Request $request
  40. * @param PaginatorInterface $paginator
  41. *
  42. * @return Response
  43. */
  44. public function indexAction(Request $request, PaginatorInterface $paginator): Response
  45. {
  46. $products = $paginator->paginate(
  47. $this->getDoctrine()->getRepository(Product::class)->findAllInStock(),
  48. $request->query->getInt('page', 1),
  49. $request->query->getInt('limit', 6)
  50. );
  51. if ($request->query->get('view') === 'largeIcons') {
  52. return $this->render(
  53. $this->isFragment($request)
  54. ? 'ECommerce/App/Product/index.ajax.twig'
  55. : 'ECommerce/App/Product/large_icons.html.twig', [
  56. 'products' => $products,
  57. ]);
  58. } else {
  59. return $this->render(
  60. $this->isFragment($request)
  61. ? 'ECommerce/App/Product/index.ajax.twig'
  62. : 'ECommerce/App/Product/index.html.twig', [
  63. 'products' => $products,
  64. ]);
  65. }
  66. }
  67. /**
  68. * Finds and displays a product entity.
  69. *
  70. * @Route("/{id}", name="mdl_app_product_show", requirements={
  71. * "id"="\d+"
  72. * }, methods="GET")
  73. *
  74. * @Cache(etag="product.getUpdatedAt().getTimestamp()", expires="+2 days", public=true)
  75. *
  76. * @param Product $product
  77. *
  78. * @return Response
  79. */
  80. public function showAction(Product $product): Response
  81. {
  82. return $this->render('ECommerce/App/Product/show.html.twig', ['product' => $product]);
  83. }
  84. /**
  85. * Finds and displays a product entity.
  86. *
  87. * @Route("/remote/{remoteId}", name="mdl_app_remote_product_show", requirements={
  88. * "remoteId"="\d+"
  89. * }, methods="GET")
  90. *
  91. * @Cache(etag="product.getUpdatedAt().getTimestamp()", expires="+2 days", public=true)
  92. *
  93. * @param Product $product
  94. *
  95. * @return Response
  96. */
  97. public function showByRemoteId(Product $product): Response
  98. {
  99. return $this->render('ECommerce/App/Product/show.html.twig', ['product' => $product]);
  100. }
  101. /**
  102. * Lists all product entities by size filter.
  103. *
  104. * @Route("/filter_by_size", name="mdl_app_product_filter_by_size", methods={"GET", "POST"})
  105. *
  106. * @param Request $request
  107. * @param PaginatorInterface $paginator
  108. * @param CacheHelper $cacheHelper
  109. *
  110. * @return Response
  111. */
  112. public function filterBySizeAction(
  113. Request $request,
  114. PaginatorInterface $paginator,
  115. CacheHelper $cacheHelper
  116. ): Response {
  117. $form = $this->createForm(ProductFilterBySize::class, null, array(
  118. 'action' => $this->generateUrl('mdl_app_product_filter_by_size'),
  119. 'method' => 'GET'
  120. ))->handleRequest($this->get('request_stack')->getMasterRequest());
  121. if ($this->isFragment($request)) {
  122. return $cacheHelper::responseCached(
  123. $this->render('ECommerce/App/Product/filter_by_size.form.twig', [
  124. 'form' => $form->createView(),
  125. ])
  126. );
  127. }
  128. $data = $form->getNormData();
  129. unset($data['precision']);
  130. $responseData = [
  131. 'form' => $form->createView(),
  132. 'products' => $paginator->paginate(
  133. $this->getDoctrine()->getRepository(Product::class)
  134. ->createBySizeQuery($form->getNormData()),
  135. (int) $request->get('page', 1),
  136. (int) $request->get('itemsPerPage', 20)
  137. ),
  138. 'title' => implode('x', array_values($data)),
  139. ];
  140. if ($request->isXmlHttpRequest()) {
  141. return $cacheHelper::responseCached(
  142. $this->render('ECommerce/App/Product/filter_by_name.ajax.twig', $responseData)
  143. );
  144. }
  145. return $cacheHelper::responseCached(
  146. $this->render('ECommerce/App/Product/filter_by_name.html.twig', $responseData)
  147. );
  148. }
  149. /**
  150. * Lists all product entities by name filter.
  151. *
  152. * @Route("/filter_by_name", name="mdl_app_product_filter_by_name")
  153. *
  154. * @Cache(expires="+2 days", public=true)
  155. *
  156. * @param Request $request
  157. * @param PaginatorInterface $paginator
  158. * @param CacheHelper $cacheHelper
  159. *
  160. * @return Response
  161. *
  162. * @throws \Doctrine\DBAL\DBALException
  163. */
  164. public function filterByNameAction(
  165. Request $request,
  166. PaginatorInterface $paginator,
  167. CacheHelper $cacheHelper
  168. ): Response {
  169. $searchTitle = $this->get('request_stack')->getMasterRequest()->get('title', '');
  170. preg_match('/^\*.*/', $searchTitle, $minQuantity);
  171. $data = array(
  172. 'title' => $searchTitle
  173. );
  174. $form = $this->createForm(ProductFilterByName::class, $data, array(
  175. 'action' => $this->generateUrl('mdl_app_product_filter_by_name'),
  176. 'method' => 'GET'
  177. ))->handleRequest($request);
  178. $title = ltrim(Index::index($form->getNormData()['title']), '*');
  179. $minQuantity = (int)(count($minQuantity) < 1);
  180. $responseData = [
  181. 'form' => $form->createView(),
  182. 'products' => $paginator->paginate(
  183. [],
  184. (int) $request->get('page', 1),
  185. (int) $request->get('itemsPerPage', 20)
  186. ),
  187. 'title' => $searchTitle,
  188. 'initialTitle' => $title,
  189. ];
  190. if ($this->isFragment($request)) {
  191. return $cacheHelper::responseCached(
  192. $this->render('ECommerce/App/Product/filter_by_name.form.twig', $responseData)
  193. ->setExpires(new DateTime('+2 days'))
  194. );
  195. }
  196. if (!$form->isSubmitted() || !$form->isValid()) {
  197. return $cacheHelper::responseCached(
  198. $this->render('ECommerce/App/Product/filter_by_name.html.twig', $responseData)
  199. ->setExpires(new DateTime('+2 days'))
  200. );
  201. }
  202. $responseData['products'] = $paginator->paginate(
  203. $this->getDoctrine()
  204. ->getRepository(Product::class)
  205. ->createLikeSearchTitleQueryBuilder($title, $minQuantity),
  206. $request->query->getInt('page', 1),
  207. $request->query->getInt('itemsPerPage', 20)
  208. );
  209. if ($request->isXmlHttpRequest() && $request->query->get('view') !== 'largeIcons') {
  210. return $cacheHelper::responseCached(
  211. $this->render('ECommerce/App/Product/filter_by_name.ajax.twig', $responseData)
  212. ->setExpires(new DateTime('+2 days'))
  213. );
  214. }
  215. return $cacheHelper::responseCached(
  216. $this->render('ECommerce/App/Product/filter_by_name.html.twig', $responseData)
  217. ->setExpires(new DateTime('+2 days'))
  218. );
  219. }
  220. /**
  221. * Lists all product entities by category.
  222. *
  223. * @Route("/filter_by_category", name="mdl_app_product_filter_by_category")
  224. *
  225. * @param Request $request
  226. * @param PaginatorInterface $paginator
  227. * @param CacheHelper $cacheHelper
  228. *
  229. * @return Response
  230. */
  231. public function filterByCategoryAction(
  232. Request $request,
  233. PaginatorInterface $paginator,
  234. CacheHelper $cacheHelper,
  235. RequestStack $requestStack,
  236. ProductCategoryRepository $categoryRepository
  237. ): Response {
  238. return new Response();
  239. $category = $requestStack->getMainRequest()->get('category');
  240. $data = array(
  241. 'category' => !empty($category) ? $categoryRepository->find($category) : null,
  242. );
  243. $form = $this->createForm(ProductFilterByCategory::class, $data, array(
  244. 'action' => $this->generateUrl('mdl_app_product_filter_by_category'),
  245. 'method' => 'GET',
  246. ))->handleRequest($request);
  247. if ($this->isFragment($request)) {
  248. return $cacheHelper::responseCached(
  249. $this->render('ECommerce/App/Product/filter_by_category.form.twig', array(
  250. 'categoryForm' => $form->createView(),
  251. ))
  252. );
  253. }
  254. if (!$form->isSubmitted() || !$form->isValid()) {
  255. return $cacheHelper::responseCached(
  256. $this->render('ECommerce/App/Product/filter_by_category.html.twig', [
  257. 'categoryForm' => $form->createView(),
  258. 'products' => $responseData['products'] = $paginator->paginate(
  259. [],
  260. (int) $request->get('page', 1),
  261. (int) $request->get('itemsPerPage', 20)
  262. ),
  263. 'title' => null,
  264. ])
  265. );
  266. }
  267. $response = array(
  268. 'categoryForm' => $form->createView(),
  269. 'products' => $responseData['products'] = $paginator->paginate(
  270. $this->getDoctrine()->getRepository(Product::class)->createByCategoryQueryBuilder($form->getNormData()['category']),
  271. (int) $request->get('page', 1),
  272. (int) $request->get('itemsPerPage', 20)
  273. ),
  274. 'title' => null,
  275. );
  276. if ($request->isXmlHttpRequest()) {
  277. return $cacheHelper::responseCached(
  278. $this->render('ECommerce/App/Product/filter_by_category.ajax.twig', $response)
  279. );
  280. }
  281. return $cacheHelper::responseCached(
  282. $this->render('ECommerce/App/Product/filter_by_category.html.twig', $response)
  283. );
  284. }
  285. public function show(Product $product): Response
  286. {
  287. return $this->render(':ECommerce/App/Product:show.html.twig', [
  288. 'product' => $product,
  289. ]);
  290. }
  291. }