Completed
Push — master ( a4551f...f2d5c9 )
by Paweł
19:10 queued 05:45
created

OrderItemController   D

Complexity

Total Complexity 34

Size/Duplication

Total Lines 271
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 24

Importance

Changes 0
Metric Value
wmc 34
lcom 1
cbo 24
dl 0
loc 271
rs 4.819
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
C addAction() 0 74 10
C removeAction() 0 52 9
A getOrderRepository() 0 4 1
A redirectToCartSummary() 0 8 2
A getCartSummaryRoute() 0 4 1
A getCurrentCart() 0 4 1
A getContext() 0 4 1
A createAddToCartCommand() 0 4 1
A getFormFactory() 0 4 1
A getQuantityModifier() 0 4 1
A getOrderModifier() 0 4 1
A getCartManager() 0 4 1
A getCartItemErrors() 0 7 1
A getAddToCartFormWithErrors() 0 8 2
A handleBadAjaxRequestView() 0 7 1
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sylius\Bundle\OrderBundle\Controller;
13
14
use Doctrine\Common\Persistence\ObjectRepository;
15
use Doctrine\ORM\EntityManagerInterface;
16
use FOS\RestBundle\View\View;
17
use Sylius\Bundle\ResourceBundle\Controller\RequestConfiguration;
18
use Sylius\Bundle\ResourceBundle\Controller\ResourceController;
19
use Sylius\Component\Order\CartActions;
20
use Sylius\Component\Order\Context\CartContextInterface;
21
use Sylius\Component\Order\Model\OrderInterface;
22
use Sylius\Component\Order\Model\OrderItemInterface;
23
use Sylius\Component\Order\Modifier\OrderItemQuantityModifierInterface;
24
use Sylius\Component\Order\Modifier\OrderModifierInterface;
25
use Symfony\Component\Form\FormError;
26
use Symfony\Component\Form\FormFactoryInterface;
27
use Symfony\Component\Form\FormInterface;
28
use Symfony\Component\HttpFoundation\RedirectResponse;
29
use Symfony\Component\HttpFoundation\Request;
30
use Symfony\Component\HttpFoundation\Response;
31
use Symfony\Component\HttpKernel\Exception\HttpException;
32
use Symfony\Component\Validator\ConstraintViolationListInterface;
33
34
/**
35
 * @author Paweł Jędrzejewski <[email protected]>
36
 */
37
class OrderItemController extends ResourceController
38
{
39
    /**
40
     * @param Request $request
41
     *
42
     * @return Response
43
     */
44
    public function addAction(Request $request)
45
    {
46
        $cart = $this->getCurrentCart();
47
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
48
49
        $this->isGrantedOr403($configuration, CartActions::ADD);
50
        /** @var OrderItemInterface $orderItem */
51
        $orderItem = $this->newResourceFactory->create($configuration, $this->factory);
52
53
        $this->getQuantityModifier()->modify($orderItem, 1);
54
55
        $form = $this->getFormFactory()->create(
56
            $configuration->getFormType(),
57
            $this->createAddToCartCommand($cart, $orderItem),
58
            $configuration->getFormOptions()
59
        );
60
61
        if ($request->isMethod('POST') && $form->handleRequest($request)->isValid()) {
62
            /** @var AddToCartCommandInterface $addCartItemCommand */
63
            $addToCartCommand = $form->getData();
64
65
            $errors = $this->getCartItemErrors($addToCartCommand->getCartItem());
66
            if (0 < count($errors)) {
67
                $form = $this->getAddToCartFormWithErrors($errors, $form);
68
69
                return $this->handleBadAjaxRequestView($configuration, $form);
70
            }
71
72
            $event = $this->eventDispatcher->dispatchPreEvent(CartActions::ADD, $configuration, $orderItem);
73
74
            if ($event->isStopped() && !$configuration->isHtmlRequest()) {
75
                throw new HttpException($event->getErrorCode(), $event->getMessage());
76
            }
77
            if ($event->isStopped()) {
78
                $this->flashHelper->addFlashFromEvent($configuration, $event);
79
80
                return $this->redirectHandler->redirectToIndex($configuration, $orderItem);
81
            }
82
83
            $this->getOrderModifier()->addToOrder($addToCartCommand->getCart(), $addToCartCommand->getCartItem());
84
85
            $cartManager = $this->getCartManager();
86
            $cartManager->persist($cart);
87
            $cartManager->flush();
88
89
            $resourceControllerEvent = $this->eventDispatcher->dispatchPostEvent(CartActions::ADD, $configuration, $orderItem);
90
            if ($resourceControllerEvent->hasResponse()) {
91
                return $resourceControllerEvent->getResponse();
92
            }
93
94
            $this->flashHelper->addSuccessFlash($configuration, CartActions::ADD, $orderItem);
95
96
            if ($request->isXmlHttpRequest()) {
97
                return $this->viewHandler->handle($configuration, View::create([], Response::HTTP_CREATED));
98
            }
99
100
            return $this->redirectHandler->redirectToResource($configuration, $orderItem);
101
        }
102
103
        if (!$configuration->isHtmlRequest()) {
104
            return $this->handleBadAjaxRequestView($configuration, $form);
105
        }
106
107
        $view = View::create()
108
            ->setData([
109
                'configuration' => $configuration,
110
                $this->metadata->getName() => $orderItem,
111
                'form' => $form->createView(),
112
            ])
113
            ->setTemplate($configuration->getTemplate(CartActions::ADD . '.html'))
114
        ;
115
116
        return $this->viewHandler->handle($configuration, $view);
117
    }
118
119
    /**
120
     * @param Request $request
121
     *
122
     * @return Response
123
     */
124
    public function removeAction(Request $request)
125
    {
126
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
127
128
        $this->isGrantedOr403($configuration, CartActions::REMOVE);
129
        /** @var OrderItemInterface $orderItem */
130
        $orderItem = $this->findOr404($configuration);
131
132
        $event = $this->eventDispatcher->dispatchPreEvent(CartActions::REMOVE, $configuration, $orderItem);
133
134
        if ($configuration->isCsrfProtectionEnabled() && !$this->isCsrfTokenValid($orderItem->getId(), $request->request->get('_csrf_token'))) {
135
            throw new HttpException(Response::HTTP_FORBIDDEN, 'Invalid csrf token.');
136
        }
137
138
        if ($event->isStopped() && !$configuration->isHtmlRequest()) {
139
            throw new HttpException($event->getErrorCode(), $event->getMessage());
140
        }
141
        if ($event->isStopped()) {
142
            $this->flashHelper->addFlashFromEvent($configuration, $event);
143
144
            return $this->redirectHandler->redirectToIndex($configuration, $orderItem);
145
        }
146
147
        $cart = $this->getCurrentCart();
148
        if ($cart !== $orderItem->getOrder()) {
149
            $this->addFlash('error', $this->get('translator')->trans('sylius.cart.cannot_modify', [], 'flashes'));
150
151
            if (!$configuration->isHtmlRequest()) {
152
                return $this->viewHandler->handle($configuration, View::create(null, Response::HTTP_NO_CONTENT));
153
            }
154
155
            return $this->redirectHandler->redirectToIndex($configuration, $orderItem);
156
        }
157
158
        $this->getOrderModifier()->removeFromOrder($cart, $orderItem);
159
160
        $this->repository->remove($orderItem);
161
162
        $cartManager = $this->getCartManager();
163
        $cartManager->persist($cart);
164
        $cartManager->flush();
165
166
        $this->eventDispatcher->dispatchPostEvent(CartActions::REMOVE, $configuration, $orderItem);
167
168
        if (!$configuration->isHtmlRequest()) {
169
            return $this->viewHandler->handle($configuration, View::create(null, Response::HTTP_NO_CONTENT));
170
        }
171
172
        $this->flashHelper->addSuccessFlash($configuration, CartActions::REMOVE, $orderItem);
173
174
        return $this->redirectHandler->redirectToIndex($configuration, $orderItem);
175
    }
176
177
    /**
178
     * @return ObjectRepository
179
     */
180
    protected function getOrderRepository()
181
    {
182
        return $this->get('sylius.repository.order');
183
    }
184
185
    /**
186
     * @param RequestConfiguration $configuration
187
     *
188
     * @return RedirectResponse
189
     */
190
    protected function redirectToCartSummary(RequestConfiguration $configuration)
191
    {
192
        if (null === $configuration->getParameters()->get('redirect')) {
193
            return $this->redirectHandler->redirectToRoute($configuration, $this->getCartSummaryRoute());
194
        }
195
196
        return $this->redirectHandler->redirectToRoute($configuration, $configuration->getParameters()->get('redirect'));
197
    }
198
199
    /**
200
     * @return string
201
     */
202
    protected function getCartSummaryRoute()
203
    {
204
        return 'sylius_cart_summary';
205
    }
206
207
    /**
208
     * @return OrderInterface
209
     */
210
    protected function getCurrentCart()
211
    {
212
        return $this->getContext()->getCart();
213
    }
214
215
    /**
216
     * @return CartContextInterface
217
     */
218
    protected function getContext()
219
    {
220
        return $this->get('sylius.context.cart');
221
    }
222
223
    /**
224
     * @param OrderInterface $cart
225
     * @param OrderItemInterface $cartItem
226
     *
227
     * @return AddToCartCommandInterface
228
     */
229
    protected function createAddToCartCommand(OrderInterface $cart, OrderItemInterface $cartItem)
230
    {
231
        return $this->get('sylius.factory.add_to_cart_command')->createWithCartAndCartItem($cart, $cartItem);
232
    }
233
234
    /**
235
     * @return FormFactoryInterface
236
     */
237
    protected function getFormFactory()
238
    {
239
        return $this->get('form.factory');
240
    }
241
242
    /**
243
     * @return OrderItemQuantityModifierInterface
244
     */
245
    protected function getQuantityModifier()
246
    {
247
        return $this->get('sylius.order_item_quantity_modifier');
248
    }
249
250
    /**
251
     * @return OrderModifierInterface
252
     */
253
    protected function getOrderModifier()
254
    {
255
        return $this->get('sylius.order_modifier');
256
    }
257
258
    /**
259
     * @return EntityManagerInterface
260
     */
261
    protected function getCartManager()
262
    {
263
        return $this->get('sylius.manager.order');
264
    }
265
266
    /**
267
     * @param OrderItemInterface $orderItem
268
     *
269
     * @return ConstraintViolationListInterface
270
     */
271
    private function getCartItemErrors(OrderItemInterface $orderItem)
272
    {
273
        return $this
274
            ->get('validator')
275
            ->validate($orderItem, null, $this->getParameter('sylius.form.type.order_item.validation_groups'))
276
        ;
277
    }
278
279
    /**
280
     * @param ConstraintViolationListInterface $errors
281
     * @param FormInterface $form
282
     *
283
     * @return FormInterface
284
     */
285
    private function getAddToCartFormWithErrors(ConstraintViolationListInterface $errors, FormInterface $form)
286
    {
287
        foreach ($errors as $error) {
288
            $form->get('cartItem')->get($error->getPropertyPath())->addError(new FormError($error->getMessage()));
289
        }
290
291
        return $form;
292
    }
293
294
    /**
295
     * @param RequestConfiguration $configuration
296
     * @param FormInterface $form
297
     *
298
     * @return Response
299
     */
300
    private function handleBadAjaxRequestView(RequestConfiguration $configuration, FormInterface $form)
301
    {
302
        return $this->viewHandler->handle(
303
            $configuration,
304
            View::create($form, Response::HTTP_BAD_REQUEST)->setData(['errors' => $form->getErrors(true, true)])
305
        );
306
    }
307
}
308