vendor/sylius/sylius/src/Sylius/Bundle/OrderBundle/Controller/OrderItemController.php line 37

Open in your IDE?
  1. <?php
  2. /*
  3. * This file is part of the Sylius package.
  4. *
  5. * (c) Paweł Jędrzejewski
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. declare(strict_types=1);
  11. namespace Sylius\Bundle\OrderBundle\Controller;
  12. use Doctrine\ORM\EntityManagerInterface;
  13. use FOS\RestBundle\View\View;
  14. use Sylius\Bundle\ResourceBundle\Controller\RequestConfiguration;
  15. use Sylius\Bundle\ResourceBundle\Controller\ResourceController;
  16. use Sylius\Component\Order\CartActions;
  17. use Sylius\Component\Order\Context\CartContextInterface;
  18. use Sylius\Component\Order\Model\OrderInterface;
  19. use Sylius\Component\Order\Model\OrderItemInterface;
  20. use Sylius\Component\Order\Modifier\OrderItemQuantityModifierInterface;
  21. use Sylius\Component\Order\Modifier\OrderModifierInterface;
  22. use Sylius\Component\Order\Repository\OrderRepositoryInterface;
  23. use Symfony\Component\Form\FormError;
  24. use Symfony\Component\Form\FormFactoryInterface;
  25. use Symfony\Component\Form\FormInterface;
  26. use Symfony\Component\HttpFoundation\Request;
  27. use Symfony\Component\HttpFoundation\Response;
  28. use Symfony\Component\HttpKernel\Exception\HttpException;
  29. use Symfony\Component\Validator\ConstraintViolationListInterface;
  30. class OrderItemController extends ResourceController
  31. {
  32. public function addAction(Request $request): Response
  33. {
  34. $cart = $this->getCurrentCart();
  35. $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
  36. $this->isGrantedOr403($configuration, CartActions::ADD);
  37. /** @var OrderItemInterface $orderItem */
  38. $orderItem = $this->newResourceFactory->create($configuration, $this->factory);
  39. $this->getQuantityModifier()->modify($orderItem, 1);
  40. $form = $this->getFormFactory()->create(
  41. $configuration->getFormType(),
  42. $this->createAddToCartCommand($cart, $orderItem),
  43. $configuration->getFormOptions(),
  44. );
  45. if ($request->isMethod('POST') && $form->handleRequest($request)->isValid()) {
  46. /** @var AddToCartCommandInterface $addToCartCommand */
  47. $addToCartCommand = $form->getData();
  48. $errors = $this->getCartItemErrors($addToCartCommand->getCartItem());
  49. if (0 < count($errors)) {
  50. $form = $this->getAddToCartFormWithErrors($errors, $form);
  51. return $this->handleBadAjaxRequestView($configuration, $form);
  52. }
  53. $event = $this->eventDispatcher->dispatchPreEvent(CartActions::ADD, $configuration, $orderItem);
  54. if ($event->isStopped() && !$configuration->isHtmlRequest()) {
  55. throw new HttpException($event->getErrorCode(), $event->getMessage());
  56. }
  57. if ($event->isStopped()) {
  58. $this->flashHelper->addFlashFromEvent($configuration, $event);
  59. return $this->redirectHandler->redirectToIndex($configuration, $orderItem);
  60. }
  61. $this->getOrderModifier()->addToOrder($addToCartCommand->getCart(), $addToCartCommand->getCartItem());
  62. $cartManager = $this->getCartManager();
  63. $cartManager->persist($cart);
  64. $cartManager->flush();
  65. $resourceControllerEvent = $this->eventDispatcher->dispatchPostEvent(CartActions::ADD, $configuration, $orderItem);
  66. if ($resourceControllerEvent->hasResponse()) {
  67. return $resourceControllerEvent->getResponse();
  68. }
  69. $this->flashHelper->addSuccessFlash($configuration, CartActions::ADD, $orderItem);
  70. if ($request->isXmlHttpRequest()) {
  71. return $this->viewHandler->handle($configuration, View::create([], Response::HTTP_CREATED));
  72. }
  73. return $this->redirectHandler->redirectToResource($configuration, $orderItem);
  74. }
  75. if (!$configuration->isHtmlRequest()) {
  76. return $this->handleBadAjaxRequestView($configuration, $form);
  77. }
  78. return $this->render(
  79. $configuration->getTemplate(CartActions::ADD . '.html'),
  80. [
  81. 'configuration' => $configuration,
  82. $this->metadata->getName() => $orderItem,
  83. 'form' => $form->createView(),
  84. ],
  85. );
  86. }
  87. public function removeAction(Request $request): Response
  88. {
  89. $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
  90. $this->isGrantedOr403($configuration, CartActions::REMOVE);
  91. /** @var OrderItemInterface $orderItem */
  92. $orderItem = $this->findOr404($configuration);
  93. $event = $this->eventDispatcher->dispatchPreEvent(CartActions::REMOVE, $configuration, $orderItem);
  94. if ($configuration->isCsrfProtectionEnabled() && !$this->isCsrfTokenValid((string) $orderItem->getId(), (string) $request->request->get('_csrf_token'))) {
  95. throw new HttpException(Response::HTTP_FORBIDDEN, 'Invalid csrf token.');
  96. }
  97. if ($event->isStopped() && !$configuration->isHtmlRequest()) {
  98. throw new HttpException($event->getErrorCode(), $event->getMessage());
  99. }
  100. if ($event->isStopped()) {
  101. $this->flashHelper->addFlashFromEvent($configuration, $event);
  102. return $this->redirectHandler->redirectToIndex($configuration, $orderItem);
  103. }
  104. $cart = $this->getCurrentCart();
  105. if ($cart !== $orderItem->getOrder()) {
  106. $this->addFlash('error', $this->get('translator')->trans('sylius.cart.cannot_modify', [], 'flashes'));
  107. if (!$configuration->isHtmlRequest()) {
  108. return $this->viewHandler->handle($configuration, View::create(null, Response::HTTP_NO_CONTENT));
  109. }
  110. return $this->redirectHandler->redirectToIndex($configuration, $orderItem);
  111. }
  112. $this->getOrderModifier()->removeFromOrder($cart, $orderItem);
  113. $this->repository->remove($orderItem);
  114. $cartManager = $this->getCartManager();
  115. $cartManager->persist($cart);
  116. $cartManager->flush();
  117. $this->eventDispatcher->dispatchPostEvent(CartActions::REMOVE, $configuration, $orderItem);
  118. if (!$configuration->isHtmlRequest()) {
  119. return $this->viewHandler->handle($configuration, View::create(null, Response::HTTP_NO_CONTENT));
  120. }
  121. $this->flashHelper->addSuccessFlash($configuration, CartActions::REMOVE, $orderItem);
  122. return $this->redirectHandler->redirectToIndex($configuration, $orderItem);
  123. }
  124. protected function getOrderRepository(): OrderRepositoryInterface
  125. {
  126. return $this->get('sylius.repository.order');
  127. }
  128. protected function redirectToCartSummary(RequestConfiguration $configuration): Response
  129. {
  130. if (null === $configuration->getParameters()->get('redirect')) {
  131. return $this->redirectHandler->redirectToRoute($configuration, $this->getCartSummaryRoute());
  132. }
  133. return $this->redirectHandler->redirectToRoute($configuration, $configuration->getParameters()->get('redirect'));
  134. }
  135. protected function getCartSummaryRoute(): string
  136. {
  137. return 'sylius_cart_summary';
  138. }
  139. protected function getCurrentCart(): OrderInterface
  140. {
  141. return $this->getContext()->getCart();
  142. }
  143. protected function getContext(): CartContextInterface
  144. {
  145. return $this->get('sylius.context.cart');
  146. }
  147. protected function createAddToCartCommand(OrderInterface $cart, OrderItemInterface $cartItem): AddToCartCommandInterface
  148. {
  149. return $this->get('sylius.factory.add_to_cart_command')->createWithCartAndCartItem($cart, $cartItem);
  150. }
  151. protected function getFormFactory(): FormFactoryInterface
  152. {
  153. return $this->get('form.factory');
  154. }
  155. protected function getQuantityModifier(): OrderItemQuantityModifierInterface
  156. {
  157. return $this->get('sylius.order_item_quantity_modifier');
  158. }
  159. protected function getOrderModifier(): OrderModifierInterface
  160. {
  161. return $this->get('sylius.order_modifier');
  162. }
  163. protected function getCartManager(): EntityManagerInterface
  164. {
  165. return $this->get('sylius.manager.order');
  166. }
  167. protected function getCartItemErrors(OrderItemInterface $orderItem): ConstraintViolationListInterface
  168. {
  169. return $this
  170. ->get('validator')
  171. ->validate($orderItem, null, $this->getParameter('sylius.form.type.order_item.validation_groups'))
  172. ;
  173. }
  174. protected function getAddToCartFormWithErrors(ConstraintViolationListInterface $errors, FormInterface $form): FormInterface
  175. {
  176. foreach ($errors as $error) {
  177. $formSelected = empty($error->getPropertyPath())
  178. ? $form->get('cartItem')
  179. : $form->get('cartItem')->get($error->getPropertyPath());
  180. $formSelected->addError(new FormError($error->getMessage()));
  181. }
  182. return $form;
  183. }
  184. protected function handleBadAjaxRequestView(RequestConfiguration $configuration, FormInterface $form): Response
  185. {
  186. return $this->viewHandler->handle(
  187. $configuration,
  188. View::create($form, Response::HTTP_BAD_REQUEST)->setData(['errors' => $form->getErrors(true, true)]),
  189. );
  190. }
  191. }