Completed
Push — upgrade ( c4e463 )
by Kamil
22:47
created

OrderItemController::getCartItemErrors()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 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);
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $resourceControllerEvent exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
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