src/Controller/Eshop/DefaultController.php line 393

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Eshop;
  3. use App\Controller\EshopController;
  4. use App\Entity\ClickAndCollect;
  5. use App\Entity\Client;
  6. use App\Entity\ClientAddress;
  7. use App\Entity\Newsletter;
  8. use App\Entity\Order;
  9. use App\Entity\Reclamation;
  10. use App\Enum\CollectEnum;
  11. use App\Enum\OrderEnum;
  12. use App\Fce\F_Ecomail;
  13. use App\Fce\F_Tree;
  14. use App\Form\Eshop\CartAddressType;
  15. use App\Form\Eshop\ContactType;
  16. use App\Form\Eshop\NewsletterType;
  17. use App\Form\Eshop\ReclamationType;
  18. use Doctrine\ORM\NonUniqueResultException;
  19. use Doctrine\ORM\NoResultException;
  20. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  21. use Symfony\Component\Form\FormInterface;
  22. use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
  23. use Symfony\Component\HttpFoundation\Cookie;
  24. use Symfony\Component\HttpFoundation\RedirectResponse;
  25. use Symfony\Component\HttpFoundation\Request;
  26. use Symfony\Component\HttpFoundation\Response;
  27. use Symfony\Component\Routing\Annotation\Route;
  28. use Symfony\Contracts\Translation\TranslatorInterface;
  29. /**
  30. * @Route("/")
  31. */
  32. class DefaultController extends EshopController
  33. {
  34. /**
  35. * @Route("", name="web_default")
  36. * @Template()
  37. *
  38. * @return array
  39. * @throws \Doctrine\ORM\NonUniqueResultException
  40. */
  41. public function index(): array
  42. {
  43. return [
  44. 'categories' => $this->categoryRepository->findAllTree(true),
  45. 'top_brands' => $this->brandRepository->getAtHomepage(),
  46. 'brands' => $this->brandRepository->findForMenu(),
  47. 'biggestDiscount' => $this->productRepository->biggestDiscount(),
  48. 'news_products' => $this->productRepository->newsProducts(),
  49. 'banner' => $this->slideRepository->getHomepage()
  50. //'banners' => $this->slideRepository->getAtHomepage()
  51. ];
  52. }
  53. /**
  54. * @Route("reklamace/", name="web_page_reclamation")
  55. * @Template()
  56. * @param Request $request
  57. * @param \Swift_Mailer $mailer
  58. *
  59. * @param TranslatorInterface $translator
  60. *
  61. * @return array|RedirectResponse
  62. */
  63. public function reclamation(Request $request, \Swift_Mailer $mailer, TranslatorInterface $translator)
  64. {
  65. $reclamation = new Reclamation();
  66. $form = $this->createForm(ReclamationType::class, $reclamation);
  67. $form->handleRequest($request);
  68. if ($form->isSubmitted() && $form->isValid()) {
  69. $order = $this->orderRepository->findForReclamation($form);
  70. if (!$order instanceof Order) {
  71. $this->addFlash('danger', $translator->trans('reclamation.notFound'));
  72. return $this->redirectToRoute('web_page_reclamation');
  73. }
  74. $reclamation->setOrder($order);
  75. $reclamation->setCreatets(new \DateTime());
  76. $reclamation->setDealer($order->getDealer());
  77. $this->em->persist($reclamation);
  78. $this->em->flush();
  79. $message = (
  80. new \Swift_Message($translator->trans('reclamation.email.subject')))
  81. ->setFrom($this->getParameter('from_email'))
  82. ->setTo($reclamation->getEmail())
  83. //->setBcc( [$this->getParameter('test_email'),$reclamation->getDealer()->getOrderEmail()] )
  84. ->setBcc(explode(',', $reclamation->getDealer()->getOrderEmail()))
  85. ->setBody($this->renderView('eshop/emails/reclamation.html.twig', ['form' => $form]), 'text/html');
  86. if ($mailer->send($message)) {
  87. $this->addFlash('success', $translator->trans('reclamation.sended'));
  88. return $this->redirectToRoute('web_default');
  89. }
  90. }
  91. return [
  92. 'form' => $form->createView(),
  93. 'categories' => $this->categoryRepository->findAllTree(true),
  94. 'brands' => $this->brandRepository->findForMenu(),
  95. 'dealers' => $this->dealerRepository->findForContacts(),
  96. ];
  97. }
  98. /**
  99. * @Route("kontakt/", name="web_page_contact")
  100. * @Template()
  101. * @param Request $request
  102. * @param \Swift_Mailer $mailer
  103. *
  104. * @param TranslatorInterface $translator
  105. *
  106. * @return array|RedirectResponse
  107. */
  108. public function contact(Request $request, \Swift_Mailer $mailer, TranslatorInterface $translator)
  109. {
  110. $form = $this->createForm(ContactType::class);
  111. $form->handleRequest($request);
  112. if ($form->isSubmitted() && $form->isValid()) {
  113. if ($this->isHoneypotFilled($form)) {
  114. $this->addFlash('success', $translator->trans('contact.sended'));
  115. return $this->redirectToRoute('web_page_contact');
  116. }
  117. if (isset($_POST['g-recaptcha-response'])) {
  118. $captcha = $_POST['g-recaptcha-response'];
  119. $secretKey = "6Lc9IQosAAAAAN1Oavyb1aiH10seSXD-0xUg05vO";
  120. $url = 'https://www.google.com/recaptcha/api/siteverify?secret=' . urlencode($secretKey) . '&response=' . urlencode($captcha);
  121. $response = file_get_contents($url);
  122. $responseKeys = json_decode($response, true, 512, JSON_THROW_ON_ERROR);
  123. // should return JSON with success as true
  124. if ($responseKeys["success"]) {
  125. $message = (
  126. new \Swift_Message('Kontaktní formulář'))
  127. ->setFrom($this->getParameter('from_email'))
  128. ->setTo($this->getParameter('contact_email'))
  129. //->setBcc( $this->getParameter('test_email') )
  130. ->setBody($this->renderView('eshop/emails/contact.html.twig', ['form' => $form]), 'text/html');
  131. if ($mailer->send($message)) {
  132. $this->addFlash('success', $translator->trans('contact.sended'));
  133. return $this->redirectToRoute('web_page_contact');
  134. }
  135. } else {
  136. $this->addFlash('danger', 'Žádost byla odeslána.');
  137. }
  138. }
  139. }
  140. return [
  141. 'form' => $form->createView(),
  142. 'categories' => $this->categoryRepository->findAllTree(true),
  143. 'brands' => $this->brandRepository->findForMenu(),
  144. 'dealers' => $this->dealerRepository->findForContacts(),
  145. ];
  146. }
  147. private function isHoneypotFilled(FormInterface $form): bool
  148. {
  149. return $form->has('website') && trim((string) $form->get('website')->getData()) !== '';
  150. }
  151. /**
  152. * @Route("click-and-collect/", name="web_page_cac")
  153. * @Route("click-and-order/", name="web_page_ord")
  154. * @Template()
  155. *
  156. * @return array
  157. */
  158. public function cac(): array
  159. {
  160. return [
  161. 'categories' => $this->categoryRepository->findAllTree(true),
  162. 'brands' => $this->brandRepository->findForMenu()
  163. ];
  164. }
  165. /**
  166. * @Route("market-place/", name="web_market_place")
  167. * @Template()
  168. *
  169. * @return array
  170. */
  171. public function marketPlace(): array
  172. {
  173. return [
  174. 'categories' => $this->categoryRepository->findAllTree(true),
  175. 'brands' => $this->brandRepository->findForMenu()
  176. ];
  177. }
  178. /**
  179. * @Route("profil/address", name="web_client_address")
  180. * @Template()
  181. *
  182. * @param Request $request
  183. *
  184. * @return array|RedirectResponse
  185. */
  186. public function profileAddress(Request $request)
  187. {
  188. /** @var Client $client */
  189. $client = $this->getUser();
  190. $billingAddress = new ClientAddress();
  191. $billingAddress->setClient($client);
  192. $deliveryAddress = new ClientAddress();
  193. $deliveryAddress->setClient($client);
  194. if ($client->getBillingAddress() instanceof ClientAddress) {
  195. $billingAddress = $client->getBillingAddress();
  196. }
  197. if ($client->getDeliveryAddress() instanceof ClientAddress) {
  198. $deliveryAddress = $client->getDeliveryAddress();
  199. }
  200. $form = $this->createFormBuilder(null, ['data_class' => Client::class, 'data' => $client])
  201. ->add('billingAddress', CartAddressType::class, ['data' => $billingAddress, 'type' => 'billing', 'data_class' => ClientAddress::class])
  202. ->add('deliveryAddress', CartAddressType::class, ['data' => $deliveryAddress, 'type' => 'delivery', 'data_class' => ClientAddress::class])
  203. ->add('hasDeliveryAddress', CheckboxType::class, ['label' => 'cart.address.hasDelivery', 'data' => $client->getHasDeliveryAddress(), 'required' => false])
  204. ->getForm();
  205. $form->handleRequest($request);
  206. if ($form->isSubmitted() && $form->isValid()) {
  207. if (empty($client->getDeliveryAddress()->getStreet())) {
  208. $client->setDeliveryAddress(null);
  209. }
  210. $this->em->persist($client);
  211. $this->em->flush();
  212. return $this->redirectToRoute('web_client_address');
  213. }
  214. return [
  215. 'categories' => $this->categoryRepository->findAllTree(true),
  216. 'brands' => $this->brandRepository->findForMenu(),
  217. 'form' => $form->createView()
  218. ];
  219. }
  220. /**
  221. * @Route("search/{search}", name="web_search")
  222. * @Route("search/", name="web_search_ape")
  223. * @param Request $request
  224. * @param $search
  225. *
  226. * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
  227. */
  228. public function search(Request $request, $search = null)
  229. {
  230. if ($search === null) {
  231. return $this->redirectToRoute('web_default');
  232. }
  233. $filters = $this->productRepository->getFiltersSearch($search);
  234. $ret = new Response();
  235. [$hash, $ret] = $this->_generateHash($request, $this->generateUrl('web_search', ['search' => $search]), $ret);
  236. $ret->setContent($this->renderView('eshop/default/search.html.twig', [
  237. 'categories' => $this->categoryRepository->findAllTree(true),
  238. 'brands' => $this->brandRepository->findForMenu(),
  239. 'search' => $search,
  240. 'filters' => $filters,
  241. 'recentlyProducts' => $this->recentlyProductRepository->getRecentlyProducts($hash, $this->getUser()),
  242. ]));
  243. return $ret;
  244. }
  245. /**
  246. * @Route("brand/{brand}", name="web_brand")
  247. * @Route("brand/", name="web_brand_ape")
  248. * @Route("dealer/{dealer}", name="web_dealer")
  249. * @Route("dealer/", name="web_dealer_ape")
  250. * @Template()
  251. * @param Request $request
  252. * @param $brand
  253. *
  254. * @param null $dealer
  255. *
  256. * @return array
  257. */
  258. public function brand(Request $request, $brand = null, $dealer = null)
  259. {
  260. $ret = new Response();
  261. if (!empty($brand)) {
  262. $entity = $brand = $this->brandRepository->findOneBy(['slug' => $brand]);
  263. $filters = $this->productRepository->getFilters($brand);
  264. [$hash, $ret] = $this->_generateHash($request, $this->generateUrl('web_brand', ['brand' => $brand->getSlug()]), $ret);
  265. } else {
  266. $entity = $dealer = $this->dealerRepository->findOneBy(['slug' => $dealer]);
  267. $filters = $this->productRepository->getFilters($dealer);
  268. [$hash, $ret] = $this->_generateHash($request, $this->generateUrl('web_dealer', ['dealer' => $dealer->getSlug()]), $ret);
  269. }
  270. $ret->setContent($this->renderView('eshop/default/brand.html.twig', [
  271. 'categories' => $this->categoryRepository->findAllTree(true),
  272. 'brands' => $this->brandRepository->findForMenu(),
  273. 'brand' => $brand,
  274. 'dealer' => $dealer,
  275. 'entity' => $entity,
  276. 'filters' => $filters,
  277. 'recentlyProducts' => $this->recentlyProductRepository->getRecentlyProducts($hash, $this->getUser())
  278. ]));
  279. return $ret;
  280. }
  281. /**
  282. * @Route("category/{slug}", name="web_category")
  283. * @param Request $request
  284. * @param $slug
  285. *
  286. * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
  287. */
  288. public function category(Request $request, $slug)
  289. {
  290. try {
  291. $categ = $this->categoryRepository->findOneBySlug($slug);
  292. } catch (NoResultException $e) {
  293. return $this->redirectToRoute('web_default');
  294. } catch (NonUniqueResultException $e) {
  295. return $this->redirectToRoute('web_default');
  296. }
  297. $categories = $this->categoryRepository->findAllTree(true);
  298. $filters = $this->productRepository->getFilters($this->categoryRepository->findAllTree(true, $categ->getId()));
  299. $filters['subs'] = F_Tree::findInTree($categories, $categ->getId());
  300. $ret = new Response();
  301. [$hash, $ret] = $this->_generateHash($request, $this->generateUrl('web_category', ['slug' => $slug]), $ret);
  302. $ret->setContent($this->renderView('eshop/default/category.html.twig', [
  303. 'category' => $categ,
  304. 'brands' => $this->brandRepository->findForMenu(),
  305. 'filters' => $filters,
  306. 'categories' => $categories,
  307. 'recentlyProducts' => $this->recentlyProductRepository->getRecentlyProducts($hash, $this->getUser()),
  308. ]));
  309. return $ret;
  310. }
  311. private function _generateHash(Request $request, $route, $ret)
  312. {
  313. $hash = $request->cookies->get('recentlyProducts');
  314. if (empty($hash)) {
  315. $hash = md5(uniqid(time(), true));
  316. $ret->headers->setCookie(new Cookie('recentlyProducts', $hash, time() + 31556926));
  317. }
  318. return [$hash, $ret];
  319. }
  320. public function _breadcrumbs($id, $categories, $product = null): Response
  321. {
  322. $tree = F_Tree::getBreadcrumbs($categories, $id);
  323. return $this->render('eshop/core/breadcrumb.html.twig', ['tree' => $tree, 'product' => $product]);
  324. }
  325. public function _newsletter(Request $request, $locale = null, $source = 'eshop')
  326. {
  327. $entity = new Newsletter();
  328. if (!empty($locale)) {
  329. $entity->setLocale($locale);
  330. $entity->setSource($source);
  331. }
  332. $form = $this->createForm(NewsletterType::class, $entity);
  333. $form->handleRequest($request);
  334. if ($form->isSubmitted()) {
  335. $entity->setCreatets(new \DateTime());
  336. $entity->setIp($_SERVER['REMOTE_ADDR']);
  337. $this->em->persist($entity);
  338. $this->em->flush();
  339. F_Ecomail::addSubscriberFromEntity($entity);
  340. return [];
  341. }
  342. if ($source === 'eshop') {
  343. return $this->render('eshop/core/newsletter.html.twig', ['form' => $form->createView()]);
  344. }
  345. return $this->render('web/core/newsletter.html.twig', ['form' => $form->createView()]);
  346. }
  347. /**
  348. * @Route("odber-vytvoren/", name="web_newsletter_add")
  349. * @Template()
  350. * @param Request $request
  351. *
  352. * @return array
  353. */
  354. public function newsletter(Request $request): array
  355. {
  356. $entity = new Newsletter();
  357. $entity->setLocale(\Locale::getDefault());
  358. $form = $this->createForm(NewsletterType::class, $entity);
  359. $form->handleRequest($request);
  360. if ($form->isSubmitted() && $form->isValid()) {
  361. $entity->setCreatets(new \DateTime());
  362. $entity->setIp($_SERVER['REMOTE_ADDR']);
  363. $this->em->persist($entity);
  364. $this->em->flush();
  365. F_Ecomail::addSubscriberFromEntity($entity);
  366. return [
  367. 'categories' => $this->categoryRepository->findAllTree(true),
  368. 'brands' => $this->brandRepository->findForMenu(),
  369. 'email' => $entity->getEmail(),
  370. 'result' => 1
  371. ];
  372. }
  373. return [
  374. 'categories' => $this->categoryRepository->findAllTree(true),
  375. 'brands' => $this->brandRepository->findForMenu(),
  376. 'email' => $entity->getEmail(),
  377. 'result' => 0
  378. ];
  379. }
  380. /**
  381. * @Route("product/{slug}", name="web_product")
  382. * @Route("product/", name="web_product_ape")
  383. * @param Request $request
  384. * @param $slug
  385. *
  386. * @return array|RedirectResponse
  387. */
  388. public function product(Request $request, $slug)
  389. {
  390. try {
  391. $product = $this->productRepository->findOneBySlug($slug);
  392. $product = $this->productRepository->getProductData([$product->getId()]);
  393. $product = reset($product);
  394. } catch (NoResultException $e) {
  395. return $this->redirectToRoute('web_default');
  396. } catch (NonUniqueResultException $e) {
  397. return $this->redirectToRoute('web_default');
  398. }
  399. $ret = new Response();
  400. [$hash, $ret] = $this->_generateHash($request, $this->generateUrl('web_product', ['slug' => $slug]), $ret);
  401. $this->recentlyProductRepository->addRecently($hash, $this->getUser(), $product['id']);
  402. $ret->setContent($this->renderView('eshop/default/product.html.twig', [
  403. 'categories' => $this->categoryRepository->findAllTree(true),
  404. 'brands' => $this->brandRepository->findForMenu(),
  405. 'recentlyProducts' => $this->recentlyProductRepository->getRecentlyProducts($hash, $this->getUser(), $product['id']),
  406. 'product' => $product,
  407. 'selectedVariant' => $request->query->get('var')
  408. ]));
  409. return $ret;
  410. }
  411. /**
  412. * @Route("rezervace/prodlouzeni/{hash}", name="web_click_and_collect_extended")
  413. * @Template()
  414. * @param TranslatorInterface $translator
  415. * @param null $hash
  416. *
  417. * @return \Symfony\Component\HttpFoundation\RedirectResponse
  418. */
  419. public function collectionExtend(TranslatorInterface $translator, $hash = null): ?RedirectResponse
  420. {
  421. $data = explode('|', base64_decode($hash));
  422. $entity = $this->clickAndCollectRepository->findOneBy(['clientEmail' => $data[0], 'number' => $data[1], 'id' => $data[2]]);
  423. if (!$entity instanceof ClickAndCollect) {
  424. return $this->redirectToRoute('web_default');
  425. }
  426. if ($entity->getExtended()) {
  427. $message = $translator->trans('extend.repeate');
  428. } else {
  429. $entity->setExtended(true);
  430. $entity->setStatus(CollectEnum::EXTENDED);
  431. $date = clone $entity->getReservedTo();
  432. $date->modify('+4 days');
  433. $entity->setReservedTo($date);
  434. $this->em->persist($entity);
  435. $this->em->flush();
  436. $message = $translator->trans('extend.success', ['%date%' => $date->format('d.m.Y H:i:s')]);
  437. }
  438. echo $message;
  439. die;
  440. }
  441. /**
  442. * @Route("objednavka/storno/{hash}", name="web_order_storno")
  443. * @Route("objednavka/storno/{hash}/{confirm}", name="web_order_storno_confirm")
  444. * @Template()
  445. * @param TranslatorInterface $translator
  446. * @param null $hash
  447. *
  448. * @param bool $confirm
  449. *
  450. * @return RedirectResponse|Response
  451. */
  452. public function orderStorno(TranslatorInterface $translator, $hash = null, $confirm = false)
  453. {
  454. $order = $this->orderRepository->findByHash($hash);
  455. $message = false;
  456. if (!$order instanceof Order) {
  457. return $this->redirectToRoute('web_default');
  458. }
  459. if ($confirm) {
  460. if ($order->getStornots() !== null) {
  461. $message = $translator->trans('order.storno.repeate');
  462. } else {
  463. $order->setStornots(new \DateTime());
  464. $order->setStatus(OrderEnum::STORNO_CLIENT);
  465. $this->em->persist($order);
  466. $this->em->flush();
  467. $message = $translator->trans('order.storno.success');
  468. }
  469. }
  470. return $this->render('eshop/order/order_storno.html.twig', [
  471. 'categories' => $this->categoryRepository->findAllTree(true),
  472. 'brands' => $this->brandRepository->findForMenu(),
  473. 'cart' => $order,
  474. 'message' => $message
  475. ]);
  476. }
  477. /**
  478. * @Route("change-currency/{code}", name="web_change_currency")
  479. * @Route("change-currency/", name="web_change_currency_ape")
  480. * @param Request $request
  481. * @param string $code
  482. *
  483. * @return RedirectResponse
  484. */
  485. public function changeCurrency(Request $request, string $code): RedirectResponse
  486. {
  487. if (!empty($code)) {
  488. $request->getSession()->set('_currency', $code);
  489. }
  490. if (!empty($request->query->get('referer'))) {
  491. return $this->redirectToRoute($request->query->get('referer'));
  492. }
  493. return $this->redirect($request->headers->get('referer', $this->generateUrl('web_default')));
  494. }
  495. /**
  496. * @Route("app/{locale}/{code}", name="web_application_texts")
  497. * @param $locale
  498. * @param string $code
  499. *
  500. * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
  501. */
  502. public function applicationTextx($locale, string $code)
  503. {
  504. switch ($code) {
  505. case 'gdpr':
  506. {
  507. return $this->render('eshop/files/gdpr_' . $locale . '.html.twig');
  508. }
  509. case 'terms-and-conditions':
  510. {
  511. return $this->render('eshop/files/terms_and_conditions_' . $locale . '.html.twig');
  512. }
  513. default:
  514. {
  515. return $this->redirectToRoute('web_default');
  516. }
  517. }
  518. }
  519. }