<?php
declare(strict_types=1);
namespace App\Controller\ECommerce\App;
use App\Entity\ECommerce\Client;
use App\Entity\ECommerce\Currency;
use App\Entity\ECommerce\DepotProduct;
use App\Entity\ECommerce\IndividualOrder;
use App\Form\ECommerce\App\IndividualOrderType;
use App\Form\ECommerce\Partials\CartItem\IndividualOrderItemQuantity;
use App\Controller\ControllerTrait;
use App\Entity\App\User;
use App\Form\App\Type\RegistrationFormType;
use App\Security\App\AuthSecurityService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* Class IndividualOrderController
*
* @package App\Controller\ECommerce\App
*
* @Route("/{_locale}/individual_order", requirements={"_locale": "\w{2}"})
*/
class IndividualOrderController extends AbstractController
{
const INDEX_ROUTE = 'mdl_public_individual_order_index';
use ControllerTrait;
/**
* @Route("/index", name="mdl_public_individual_order_index", methods={"GET", "POST"})
*
* @param Request $request
*
* @return Response
*/
public function indexAction(Request $request): Response
{
/** @var IndividualOrder $order */
$order = $this->get('session')->get('individual_order', new IndividualOrder());
$form = $this->createForm(IndividualOrderType::class, $order)->handleRequest($request);
$products = $this->getDoctrine()
->getRepository(DepotProduct::class)
->findById(array_keys($order->getItems()));
if (!$form->isSubmitted() || !$form->isValid()) {
return $this->render('ECommerce/App/IndividualOrder/index.html.twig', [
'products' => $products,
'individual_order' => $order,
'form' => $form->createView(),
]);
}
return $this->redirectToRoute('mdl_public_individual_order_checkout');
}
/**
* @Route("/checkout", name="mdl_public_individual_order_checkout", methods={"GET", "POST"})
*
* @param Request $request
* @param TranslatorInterface $translator
* @param AuthSecurityService $securityService
*
* @return Response
*
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function checkOut(Request $request, TranslatorInterface $translator, AuthSecurityService $securityService): Response
{
/** @var IndividualOrder $order */
$order = $this->get('session')->get('individual_order');
if (!$order) {
$this->addFlash(
'danger',
$translator->trans('notifications.individual_order.empty', [], 'ECommerceBundle')
);
return $this->redirectToIndex();
}
$currency = $this->getDoctrine()->getRepository(Currency::class)->findFirst();
$user = $this->getUser();
if($user instanceof User) {
$em = $this->getDoctrine()->getManager();
$em->persist($order->setUser($user));
$em->flush();
$this->get('session')->remove('individual_order');
$this->addFlash(
'success',
$translator->trans('notifications.individual_order.success', [], 'ECommerceBundle')
);
return $this->redirectToPublicIndex();
}
$user = (new User())->setPassword(microtime())
->setGuest(true)
->setClient((new Client())->setPhones([''])
->setCurrency($currency));
$form = $this->createForm(RegistrationFormType::class, $user, array(
'short' => true,
'validation_groups' => ['Registration'],
'translation_domain' => 'validators',
))->handleRequest($request);
if ($form->isSubmitted() && !$form->isValid()) {
$existingUser = $this->getDoctrine()->getRepository(User::class)->findOneBy(['email' => $user->getEmail()]);
if ($existingUser) {
return $this->redirectToRoute('mdl_public_individual_order_check_out', [
'email' => $user->getEmail()
]);
}
}
if (!$form->isSubmitted() || !$form->isValid()) {
return $this->render('ECommerce/App/IndividualOrder/checkout.html.twig', [
'individual_order' => $order,
'form' => $form->createView(),
'user' => $user,
]);
}
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->persist($order->setUser($user));
$em->flush();
$this->get('session')->remove('individual_order');
$securityService->login($user);
$this->addFlash(
'success',
$translator->trans('notifications.individual_order.success', [], 'ECommerceBundle')
);
return $this->redirectToPublicIndex();
}
/**
* @Route("/check_out", name="mdl_public_individual_order_check_out", methods={"GET", "POST"})
*
* @param Request $request
* @param TranslatorInterface $translator
*
* @return Response
*/
public function checkOutByUser(Request $request, TranslatorInterface $translator): Response
{
/** @var IndividualOrder $order */
$order = $this->get('session')->get('individual_order');
$user = $this->getDoctrine()->getRepository(User::class)->findOneBy([
'email' => $request->query->get('email'),
]);
if (!$user) {
return $this->redirectToIndex();
}
if (!$order) {
$this->addFlash(
'danger',
$translator->trans('notifications.individual_order.empty', [], 'ECommerceBundle')
);
return $this->redirectToIndex();
}
$em = $this->getDoctrine()->getManager();
$em->persist($order->setUser($user));
$em->flush();
$this->get('session')->remove('individual_order');
$this->get('mdl.user.security')->login($user);
$this->addFlash(
'success',
$translator->trans('notifications.individual_order.success', [], 'ECommerceBundle')
);
return $this->redirectToPublicIndex();
}
/**
* @Route("/{id}/add", name="mdl_public_individual_order_add_product", methods={"POST"})
*
* @param Request $request
* @param DepotProduct $depotProduct
* @param TranslatorInterface $translator
*
* @return RedirectResponse
*/
public function addAction(Request $request, DepotProduct $depotProduct, TranslatorInterface $translator): RedirectResponse
{
$individual_order = $this->get('session')->get('individual_order');
$individual_order = $individual_order ?? new IndividualOrder();
$form = $this->createForm(IndividualOrderItemQuantity::class, array())->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$individual_order->addItem($depotProduct, $form->getNormData()['quantity']);
$this->get('session')->set('individual_order', $individual_order);
$this->addFlash(
'success',
$translator->trans('notifications.individual_order.added', [], 'ECommerceBundle')
);
}
return $this->redirect($request->server->get('HTTP_REFERER'));
}
/**
* Update cart item quantity
*
* @Route("/{id}/quantity", name="mdl_public_individual_order_item_quantity", methods={"GET", "PATCH"})
*
* @Cache(maxage="+2 days", public=true)
*
* @param Request $request
* @param DepotProduct $depotProduct $depotProduct
* @param TranslatorInterface $translator
*
* @return Response
*/
public function quantityAction(Request $request, DepotProduct $depotProduct, TranslatorInterface $translator): Response
{
/** @var IndividualOrder $order */
$order = $this->get('session')->get('individual_order');
/** @var Form $form */
$form = $this->createForm(IndividualOrderItemQuantity::class, $depotProduct->setQuantity($order->getQuantity($depotProduct)), array(
'method' => 'PATCH',
'action' => $this->generateUrl('mdl_public_individual_order_item_quantity', array('id' => $depotProduct->getId()))
))->handleRequest($request);
$isFragment = $this->isFragment($request);
$responseData = array(
'form' => $form->createView(),
);
if (!$form->isSubmitted() || !$form->isValid()) {
return $isFragment
? $this->render('ECommerce/App/IndividualOrder/quantity.ajax.twig', $responseData)
: $this->render('ECommerce/App/IndividualOrder/quantity.html.twig', $responseData);
}
$quantity = $depotProduct->getQuantity();
if ($form->get('plus')->isSubmitted()) {
$quantity+=1;
} elseif ($form->get('minus')->isSubmitted()) {
$quantity-=1;
}
if ($quantity < 1) {
$quantity = 1;
}
$order->setQuantity($depotProduct->setQuantity($quantity));
$this->get('session')->set('individual_order', $order);
$this->addFlash(
'success',
$translator->trans('notifications.cart.quantity', [], 'ECommerceBundle')
);
return $isFragment || $request->isXmlHttpRequest()
? $this->render('ECommerce/App/IndividualOrder/quantity.ajax.twig', $responseData)
: $this->redirectToIndex();
}
/**
* Update cart item quantity
*
* @Route("/{id}/quantity", name="mdl_public_individual_order_item_remove", methods={"DELETE"})
*
* @Cache(maxage="+2 days", public=true)
*
* @param Request $request
* @param DepotProduct $depotProduct $depotProduct
* @param TranslatorInterface $translator
*
* @return Response
*/
public function removeAction(Request $request, DepotProduct $depotProduct, TranslatorInterface $translator): Response
{
/** @var IndividualOrder $order */
$order = $this->get('session')->get('individual_order');
$form = $this->getRemoveForm($depotProduct)->handleRequest($request);
if ($this->isFragment($request)) {
return $this->render('ECommerce/App/IndividualOrder/remove.ajax.twig', array(
'form' => $form->createView(),
));
}
if (!$form->isSubmitted() || !$form->isValid()) {
return $this->render('ECommerce/App/IndividualOrder/remove.ajax.twig', array(
'form' => $form->createView(),
));
}
$order->removeItem($depotProduct);
$this->get('session')->set('individual_order', $order);
$this->addFlash(
'success',
$translator->trans('notifications.cart.removed', [], 'ECommerceBundle')
);
return $this->redirectToIndex();
}
/**
* @param DepotProduct $depotProduct
*
* @return FormInterface
*/
private function getRemoveForm(DepotProduct $depotProduct): FormInterface
{
return $this->createFormBuilder()
->setAction($this->generateUrl('mdl_public_individual_order_item_remove', array('id' => $depotProduct->getId())))
->setMethod('DELETE')
->getForm();
}
/**
* @Route("/individual_order", name="mdl_public_individual_order_small_widget")
*
* @return Response
*/
public function smallWidgetAction(): Response
{
return $this->render('ECommerce/App/IndividualOrder/small_widget.html.twig', [
'individual_order' => $this->get('session')->get('individual_order'),
]);
}
}