Completed
Push — master ( 95f92c...954431 )
by
unknown
17s queued 12s
created

CartController::executePreAddToCartPlugins()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 2
1
<?php
2
3
/**
4
 * Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
5
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6
 */
7
8
namespace SprykerShop\Yves\CartPage\Controller;
9
10
use Generated\Shared\Transfer\ItemTransfer;
11
use Generated\Shared\Transfer\ProductOptionTransfer;
12
use Spryker\Yves\Kernel\PermissionAwareTrait;
13
use SprykerShop\Shared\CartPage\Plugin\AddCartItemPermissionPlugin;
14
use SprykerShop\Shared\CartPage\Plugin\ChangeCartItemPermissionPlugin;
15
use SprykerShop\Shared\CartPage\Plugin\RemoveCartItemPermissionPlugin;
16
use SprykerShop\Yves\CartPage\Plugin\Provider\CartControllerProvider;
17
use SprykerShop\Yves\ShopApplication\Controller\AbstractController;
18
use Symfony\Component\HttpFoundation\RedirectResponse;
19
use Symfony\Component\HttpFoundation\Request;
20
21
/**
22
 * @method \SprykerShop\Yves\CartPage\CartPageFactory getFactory()
23
 */
24
class CartController extends AbstractController
25
{
26
    use PermissionAwareTrait;
27
28
    public const MESSAGE_PERMISSION_FAILED = 'global.permission.failed';
29
30
    public const PARAM_ITEMS = 'items';
31
32
    protected const FIELD_QUANTITY_TO_NORMALIZE = 'quantity';
33
34
    /**
35
     * @param \Symfony\Component\HttpFoundation\Request $request
36
     *
37
     * @return \Spryker\Yves\Kernel\View\View
38
     */
39
    public function indexAction(Request $request)
40
    {
41
        $viewData = $this->executeIndexAction($request->get('selectedAttributes', []));
42
43
        return $this->view(
44
            $viewData,
45
            $this->getFactory()->getCartPageWidgetPlugins(),
46
            '@CartPage/views/cart/cart.twig'
47
        );
48
    }
49
50
    /**
51
     * @param array $selectedAttributes
52
     *
53
     * @return array
54
     */
55
    protected function executeIndexAction(array $selectedAttributes = []): array
56
    {
57
        $validateQuoteResponseTransfer = $this->getFactory()
58
            ->getCartClient()
59
            ->validateQuote();
60
61
        $this->getFactory()
62
            ->getZedRequestClient()
63
            ->addResponseMessagesToMessenger();
64
65
        $quoteTransfer = $validateQuoteResponseTransfer->getQuoteTransfer();
66
67
        $cartItems = $this->getFactory()
68
            ->createCartItemReader()
69
            ->getCartItems($quoteTransfer);
70
71
        $itemAttributesBySku = $this->getFactory()
72
            ->createCartItemsAttributeProvider()
73
            ->getItemsAttributes($quoteTransfer, $this->getLocale(), $selectedAttributes);
74
75
        $quoteClient = $this->getFactory()->getQuoteClient();
76
77
        return [
78
            'cart' => $quoteTransfer,
79
            'isQuoteEditable' => $quoteClient->isQuoteEditable($quoteTransfer),
80
            'isQuoteLocked' => $quoteClient->isQuoteLocked($quoteTransfer),
81
            'cartItems' => $cartItems,
82
            'attributes' => $itemAttributesBySku,
83
            'isQuoteValid' => $validateQuoteResponseTransfer->getIsSuccessful(),
84
        ];
85
    }
86
87
    /**
88
     * @param \Symfony\Component\HttpFoundation\Request $request
89
     * @param string $sku
90
     *
91
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
92
     */
93
    public function addAction(Request $request, $sku)
94
    {
95
        $quantity = $request->get('quantity', 1);
96
97
        if (!$this->canAddCartItem()) {
98
            $this->addErrorMessage(static::MESSAGE_PERMISSION_FAILED);
99
100
            return $this->redirectResponseInternal(CartControllerProvider::ROUTE_CART);
101
        }
102
103
        $itemTransfer = new ItemTransfer();
104
        $itemTransfer
105
            ->setSku($sku)
106
            ->setQuantity($quantity);
107
108
        $this->addProductOptions($request->get('product-option', []), $itemTransfer);
109
110
        $itemTransfer = $this->executePreAddToCartPlugins($itemTransfer, $request->request->all());
111
112
        $this->getFactory()
113
            ->getCartClient()
114
            ->addItem($itemTransfer, $request->request->all());
115
116
        $this->getFactory()
117
            ->getZedRequestClient()
118
            ->addResponseMessagesToMessenger();
119
120
        return $this->redirectResponseInternal(CartControllerProvider::ROUTE_CART);
121
    }
122
123
    /**
124
     * @param \Symfony\Component\HttpFoundation\Request $request
125
     * @param string $sku
126
     *
127
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
128
     */
129
    public function quickAddAction(Request $request, string $sku): RedirectResponse
130
    {
131
        $quantity = $request->get('quantity', 1);
132
133
        if (!$this->canAddCartItem()) {
134
            $this->addErrorMessage(static::MESSAGE_PERMISSION_FAILED);
135
136
            return $this->redirectResponseInternal(CartControllerProvider::ROUTE_CART);
137
        }
138
139
        return $this->executeQuickAddAction($sku, $quantity);
140
    }
141
142
    /**
143
     * @param string $sku
144
     * @param int $quantity
145
     *
146
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
147
     */
148
    protected function executeQuickAddAction(string $sku, int $quantity): RedirectResponse
149
    {
150
        $itemTransfer = (new ItemTransfer())
151
            ->setSku($sku)
152
            ->setQuantity($quantity)
153
            ->addNormalizableField(static::FIELD_QUANTITY_TO_NORMALIZE)
154
            ->setGroupKeyPrefix(uniqid('', true));
155
156
        $this->getFactory()
157
            ->getCartClient()
158
            ->addItem($itemTransfer);
159
160
        $this->getFactory()
161
            ->getZedRequestClient()
162
            ->addFlashMessagesFromLastZedRequest();
163
164
        return $this->redirectResponseInternal(CartControllerProvider::ROUTE_CART);
165
    }
166
167
    /**
168
     * @param \Symfony\Component\HttpFoundation\Request $request
169
     * @param string $sku
170
     *
171
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
172
     */
173
    public function removeAction(Request $request, $sku)
174
    {
175
        $groupKey = $request->get('groupKey', null);
176
177
        if (!$this->canRemoveCartItem()) {
178
            $this->addErrorMessage(static::MESSAGE_PERMISSION_FAILED);
179
180
            return $this->redirectResponseInternal(CartControllerProvider::ROUTE_CART);
181
        }
182
183
        $this->getFactory()
184
            ->getCartClient()
185
            ->removeItem($sku, $groupKey);
186
187
        $this->getFactory()
188
            ->getZedRequestClient()
189
            ->addResponseMessagesToMessenger();
190
191
        return $this->redirectResponseInternal(CartControllerProvider::ROUTE_CART);
192
    }
193
194
    /**
195
     * @param \Symfony\Component\HttpFoundation\Request $request
196
     * @param string $sku
197
     *
198
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
199
     */
200
    public function changeAction(Request $request, $sku)
201
    {
202
        $quantity = $request->get('quantity', 1);
203
204
        if (!$this->canChangeCartItem($quantity)) {
205
            $this->addErrorMessage(static::MESSAGE_PERMISSION_FAILED);
206
207
            return $this->redirectResponseInternal(CartControllerProvider::ROUTE_CART);
208
        }
209
210
        $this->getFactory()
211
            ->getCartClient()
212
            ->changeItemQuantity($sku, $request->get('groupKey'), $quantity);
213
214
        $this->getFactory()
215
            ->getZedRequestClient()
216
            ->addResponseMessagesToMessenger();
217
218
        return $this->redirectResponseInternal(CartControllerProvider::ROUTE_CART);
219
    }
220
221
    /**
222
     * @param \Symfony\Component\HttpFoundation\Request $request
223
     *
224
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
225
     */
226
    public function addItemsAction(Request $request)
227
    {
228
        if (!$this->canAddCartItem()) {
229
            $this->addErrorMessage(static::MESSAGE_PERMISSION_FAILED);
230
231
            return $this->redirectResponseInternal(CartControllerProvider::ROUTE_CART);
232
        }
233
234
        $items = (array)$request->request->get(self::PARAM_ITEMS);
235
        $itemTransfers = $this->mapItems($items);
236
237
        $this->getFactory()
238
            ->getCartClient()
239
            ->addItems($itemTransfers, $request->request->all());
240
241
        $this->getFactory()
242
            ->getZedRequestClient()
243
            ->addResponseMessagesToMessenger();
244
245
        return $this->redirectResponseInternal(CartControllerProvider::ROUTE_CART);
246
    }
247
248
    /**
249
     * @param \Symfony\Component\HttpFoundation\Request $request
250
     * @param string $sku
251
     *
252
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
253
     */
254
    public function updateAction(Request $request, $sku)
255
    {
256
        $quantity = $request->get('quantity', 1);
257
258
        if (!$this->canChangeCartItem($quantity)) {
259
            $this->addErrorMessage(static::MESSAGE_PERMISSION_FAILED);
260
261
            return $this->redirectResponseInternal(CartControllerProvider::ROUTE_CART);
262
        }
263
264
        $quoteTransfer = $this->getFactory()
265
            ->getCartClient()
266
            ->getQuote();
267
268
        $isItemReplacedInCart = $this->getFactory()
269
            ->createCartItemsAttributeProvider()
270
            ->tryToReplaceItem(
271
                $sku,
272
                $quantity,
273
                array_replace($request->get('selectedAttributes', []), $request->get('preselectedAttributes', [])),
274
                $quoteTransfer->getItems(),
275
                $request->get('groupKey'),
276
                $request->get('product-option', []),
277
                $this->getLocale()
278
            );
279
280
        if ($isItemReplacedInCart) {
281
            return $this->redirectResponseInternal(CartControllerProvider::ROUTE_CART);
282
        }
283
284
        $this->addInfoMessage('cart.item_attributes_needed');
285
286
        return $this->redirectResponseInternal(
287
            CartControllerProvider::ROUTE_CART,
288
            $this->getFactory()
289
                ->createCartItemsAttributeProvider()
290
                ->formatUpdateActionResponse($sku, $request->get('selectedAttributes', []))
291
        );
292
    }
293
294
    /**
295
     * @param array $items
296
     *
297
     * @return \Generated\Shared\Transfer\ItemTransfer[]
298
     */
299
    protected function mapItems(array $items)
300
    {
301
        $itemTransfers = [];
302
303
        foreach ($items as $item) {
304
            $itemTransfer = new ItemTransfer();
305
            $itemTransfer->fromArray($item, true);
306
            $itemTransfers[] = $itemTransfer;
307
        }
308
309
        return $itemTransfers;
310
    }
311
312
    /**
313
     * @param array $optionValueUsageIds
314
     * @param \Generated\Shared\Transfer\ItemTransfer $itemTransfer
315
     *
316
     * @return void
317
     */
318
    protected function addProductOptions(array $optionValueUsageIds, ItemTransfer $itemTransfer)
319
    {
320
        foreach ($optionValueUsageIds as $idOptionValueUsage) {
321
            if (!$idOptionValueUsage) {
322
                continue;
323
            }
324
325
            $productOptionTransfer = new ProductOptionTransfer();
326
            $productOptionTransfer->setIdProductOptionValue($idOptionValueUsage);
327
328
            $itemTransfer->addProductOption($productOptionTransfer);
329
        }
330
    }
331
332
    /**
333
     * @return bool
334
     */
335
    protected function canAddCartItem(): bool
336
    {
337
        return $this->canPerformCartItemAction(AddCartItemPermissionPlugin::KEY);
338
    }
339
340
    /**
341
     * @param int|null $itemQuantity
342
     *
343
     * @return bool
344
     */
345
    protected function canChangeCartItem(?int $itemQuantity = null): bool
346
    {
347
        if ($itemQuantity === 0) {
348
            return $this->canRemoveCartItem();
349
        }
350
351
        return $this->canPerformCartItemAction(ChangeCartItemPermissionPlugin::KEY);
352
    }
353
354
    /**
355
     * @return bool
356
     */
357
    protected function canRemoveCartItem(): bool
358
    {
359
        return $this->canPerformCartItemAction(RemoveCartItemPermissionPlugin::KEY);
360
    }
361
362
    /**
363
     * @param string $permissionPluginKey
364
     *
365
     * @return bool
366
     */
367
    protected function canPerformCartItemAction(string $permissionPluginKey): bool
368
    {
369
        $quoteTransfer = $this->getFactory()
370
            ->getCartClient()
371
            ->getQuote();
372
373
        if ($quoteTransfer->getCustomer() === null) {
374
            return true;
375
        }
376
377
        if ($quoteTransfer->getCustomer()->getCompanyUserTransfer() === null) {
378
            return true;
379
        }
380
381
        if ($this->can($permissionPluginKey)) {
382
            return true;
383
        }
384
385
        return false;
386
    }
387
388
    /**
389
     * @param \Generated\Shared\Transfer\ItemTransfer $itemTransfer
390
     * @param array $params
391
     *
392
     * @return \Generated\Shared\Transfer\ItemTransfer
393
     */
394
    protected function executePreAddToCartPlugins(ItemTransfer $itemTransfer, array $params): ItemTransfer
395
    {
396
        foreach ($this->getFactory()->getPreAddToCartPlugins() as $preAddToCartPlugin) {
397
            $itemTransfer = $preAddToCartPlugin->preAddToCart($itemTransfer, $params);
398
        }
399
400
        return $itemTransfer;
401
    }
402
}
403