<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Sylius\Bundle\OrderBundle\Controller;
use FOS\RestBundle\View\View;
use Sylius\Bundle\ResourceBundle\Controller\RequestConfiguration;
use Sylius\Bundle\ResourceBundle\Controller\ResourceController;
use Sylius\Component\Order\Context\CartContextInterface;
use Sylius\Component\Order\Model\OrderInterface;
use Sylius\Component\Order\Repository\OrderRepositoryInterface;
use Sylius\Component\Order\SyliusCartEvents;
use Sylius\Component\Resource\ResourceActions;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
class OrderController extends ResourceController
{
public function summaryAction(Request $request): Response
{
$configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
$cart = $this->getCurrentCart();
if (null !== $cart->getId()) {
$cart = $this->getOrderRepository()->findCartById($cart->getId());
}
if (!$configuration->isHtmlRequest()) {
return $this->viewHandler->handle($configuration, View::create($cart));
}
$form = $this->resourceFormFactory->create($configuration, $cart);
$view = View::create()
->setTemplate($configuration->getTemplate('summary.html'))
->setData([
'cart' => $cart,
'form' => $form->createView(),
])
;
return $this->viewHandler->handle($configuration, $view);
}
public function widgetAction(Request $request): Response
{
$configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
$cart = $this->getCurrentCart();
if (!$configuration->isHtmlRequest()) {
return $this->viewHandler->handle($configuration, View::create($cart));
}
$view = View::create()
->setTemplate($configuration->getTemplate('summary.html'))
->setData(['cart' => $cart])
;
return $this->viewHandler->handle($configuration, $view);
}
public function saveAction(Request $request): Response
{
$configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
$this->isGrantedOr403($configuration, ResourceActions::UPDATE);
$resource = $this->getCurrentCart();
$form = $this->resourceFormFactory->create($configuration, $resource);
if (in_array($request->getMethod(), ['POST', 'PUT', 'PATCH'], true) && $form->handleRequest($request)->isValid()) {
$resource = $form->getData();
$event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::UPDATE, $configuration, $resource);
if ($event->isStopped() && !$configuration->isHtmlRequest()) {
throw new HttpException($event->getErrorCode(), $event->getMessage());
}
if ($event->isStopped()) {
$this->flashHelper->addFlashFromEvent($configuration, $event);
return $this->redirectHandler->redirectToResource($configuration, $resource);
}
if ($configuration->hasStateMachine()) {
$this->stateMachine->apply($configuration, $resource);
}
$this->eventDispatcher->dispatchPostEvent(ResourceActions::UPDATE, $configuration, $resource);
$this->getEventDispatcher()->dispatch(SyliusCartEvents::CART_CHANGE, new GenericEvent($resource));
$this->manager->flush();
if (!$configuration->isHtmlRequest()) {
return $this->viewHandler->handle($configuration, View::create(null, Response::HTTP_NO_CONTENT));
}
$this->flashHelper->addSuccessFlash($configuration, ResourceActions::UPDATE, $resource);
return $this->redirectHandler->redirectToResource($configuration, $resource);
}
if (!$configuration->isHtmlRequest()) {
return $this->viewHandler->handle($configuration, View::create($form, Response::HTTP_BAD_REQUEST));
}
$view = View::create()
->setData([
'configuration' => $configuration,
$this->metadata->getName() => $resource,
'form' => $form->createView(),
'cart' => $resource,
])
->setTemplate($configuration->getTemplate(ResourceActions::UPDATE . '.html'))
;
return $this->viewHandler->handle($configuration, $view);
}
public function clearAction(Request $request): Response
{
$configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
$this->isGrantedOr403($configuration, ResourceActions::DELETE);
$resource = $this->getCurrentCart();
if ($configuration->isCsrfProtectionEnabled() && !$this->isCsrfTokenValid((string) $resource->getId(), $request->get('_csrf_token'))) {
throw new HttpException(Response::HTTP_FORBIDDEN, 'Invalid csrf token.');
}
$event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::DELETE, $configuration, $resource);
if ($event->isStopped() && !$configuration->isHtmlRequest()) {
throw new HttpException($event->getErrorCode(), $event->getMessage());
}
if ($event->isStopped()) {
$this->flashHelper->addFlashFromEvent($configuration, $event);
return $this->redirectHandler->redirectToIndex($configuration, $resource);
}
$this->repository->remove($resource);
$this->eventDispatcher->dispatchPostEvent(ResourceActions::DELETE, $configuration, $resource);
if (!$configuration->isHtmlRequest()) {
return $this->viewHandler->handle($configuration, View::create(null, Response::HTTP_NO_CONTENT));
}
$this->flashHelper->addSuccessFlash($configuration, ResourceActions::DELETE, $resource);
return $this->redirectHandler->redirectToIndex($configuration, $resource);
}
protected function redirectToCartSummary(RequestConfiguration $configuration): Response
{
if (null === $configuration->getParameters()->get('redirect')) {
return $this->redirectHandler->redirectToRoute($configuration, $this->getCartSummaryRoute());
}
return $this->redirectHandler->redirectToRoute($configuration, $configuration->getParameters()->get('redirect'));
}
protected function getCartSummaryRoute(): string
{
return 'sylius_cart_summary';
}
protected function getCurrentCart(): OrderInterface
{
return $this->getContext()->getCart();
}
protected function getContext(): CartContextInterface
{
return $this->get('sylius.context.cart');
}
protected function getOrderRepository(): OrderRepositoryInterface
{
return $this->get('sylius.repository.order');
}
protected function getEventDispatcher(): EventDispatcherInterface
{
return $this->container->get('event_dispatcher');
}
}