Skip to content

Commit 0e8cf92

Browse files
committed
Update cart items with customizable options
1 parent 18dc53f commit 0e8cf92

File tree

3 files changed

+150
-12
lines changed

3 files changed

+150
-12
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\QuoteGraphQl\Model\Cart;
9+
10+
use Magento\Framework\DataObject;
11+
use Magento\Framework\DataObjectFactory;
12+
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
14+
use Magento\Quote\Model\Quote;
15+
16+
/**
17+
* Update cart item
18+
*
19+
*/
20+
class UpdateCartItem
21+
{
22+
/**
23+
* @var DataObjectFactory
24+
*/
25+
private $dataObjectFactory;
26+
27+
/**
28+
* @param DataObjectFactory $dataObjectFactory
29+
*/
30+
public function __construct(
31+
DataObjectFactory $dataObjectFactory
32+
) {
33+
$this->dataObjectFactory = $dataObjectFactory;
34+
}
35+
36+
/**
37+
* Update cart item
38+
*
39+
* @param Quote $cart
40+
* @param int $cartItemId
41+
* @param float $qty
42+
* @param null $customizableOptionsData
43+
* @return void
44+
* @throws GraphQlInputException
45+
*/
46+
public function execute(Quote $cart, int $cartItemId, float $qty, array $customizableOptionsData): void
47+
{
48+
$customizableOptions = [];
49+
foreach ($customizableOptionsData as $customizableOption) {
50+
$customizableOptions[$customizableOption['id']] = $customizableOption['value'];
51+
}
52+
53+
try {
54+
$result = $cart->updateItem(
55+
$cartItemId,
56+
$this->createBuyRequest($qty, $customizableOptions)
57+
);
58+
} catch (LocalizedException $e) {
59+
throw new GraphQlInputException(
60+
__(
61+
'Could not update cart item: %message',
62+
['message' => $e->getMessage()]
63+
)
64+
);
65+
}
66+
67+
if (is_string($result)) {
68+
throw new GraphQlInputException(__(
69+
'Could not update cart item: %message',
70+
['message' => $result]
71+
));
72+
}
73+
74+
if ($result->getHasError()) {
75+
throw new GraphQlInputException(__(
76+
'Could not update cart item: %message',
77+
['message' => $result->getMessage()]
78+
));
79+
}
80+
}
81+
82+
/**
83+
* Format GraphQl input data to a shape that buy request has
84+
*
85+
* @param float $qty
86+
* @param array $customOptions
87+
* @return DataObject
88+
*/
89+
private function createBuyRequest(float $qty, array $customOptions): DataObject
90+
{
91+
return $this->dataObjectFactory->create([
92+
'data' => [
93+
'qty' => $qty,
94+
'options' => $customOptions,
95+
],
96+
]);
97+
}
98+
}

app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,26 @@
1515
use Magento\Framework\GraphQl\Query\ResolverInterface;
1616
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
1717
use Magento\Quote\Api\CartItemRepositoryInterface;
18+
use Magento\Quote\Api\CartRepositoryInterface;
1819
use Magento\Quote\Model\Quote;
1920
use Magento\QuoteGraphQl\Model\Cart\GetCartForUser;
21+
use Magento\QuoteGraphQl\Model\Cart\UpdateCartItem;
2022

2123
/**
2224
* @inheritdoc
2325
*/
2426
class UpdateCartItems implements ResolverInterface
2527
{
28+
/**
29+
* @var CartRepositoryInterface
30+
*/
31+
private $quoteRepository;
32+
33+
/**
34+
* @var UpdateCartItem
35+
*/
36+
private $updateCartItem;
37+
2638
/**
2739
* @var GetCartForUser
2840
*/
@@ -36,13 +48,19 @@ class UpdateCartItems implements ResolverInterface
3648
/**
3749
* @param GetCartForUser $getCartForUser
3850
* @param CartItemRepositoryInterface $cartItemRepository
51+
* @param UpdateCartItem $updateCartItem
52+
* @param CartRepositoryInterface $quoteRepository
3953
*/
4054
public function __construct(
4155
GetCartForUser $getCartForUser,
42-
CartItemRepositoryInterface $cartItemRepository
56+
CartItemRepositoryInterface $cartItemRepository,
57+
UpdateCartItem $updateCartItem,
58+
CartRepositoryInterface $quoteRepository
4359
) {
4460
$this->getCartForUser = $getCartForUser;
4561
$this->cartItemRepository = $cartItemRepository;
62+
$this->updateCartItem = $updateCartItem;
63+
$this->quoteRepository = $quoteRepository;
4664
}
4765

4866
/**
@@ -93,26 +111,47 @@ private function processCartItems(Quote $cart, array $items): void
93111
if (!isset($item['cart_item_id']) || empty($item['cart_item_id'])) {
94112
throw new GraphQlInputException(__('Required parameter "cart_item_id" for "cart_items" is missing.'));
95113
}
96-
$itemId = $item['cart_item_id'];
114+
$itemId = (int)$item['cart_item_id'];
97115

98116
if (!isset($item['quantity'])) {
99117
throw new GraphQlInputException(__('Required parameter "quantity" for "cart_items" is missing.'));
100118
}
101119
$qty = (float)$item['quantity'];
102120

103-
$cartItem = $cart->getItemById($itemId);
104-
if ($cartItem === false) {
105-
throw new GraphQlNoSuchEntityException(
106-
__('Could not find cart item with id: %1.', $item['cart_item_id'])
107-
);
108-
}
109-
110121
if ($qty <= 0.0) {
111122
$this->cartItemRepository->deleteById((int)$cart->getId(), $itemId);
112123
} else {
113-
$cartItem->setQty($qty);
114-
$this->cartItemRepository->save($cartItem);
124+
$customizableOptions = $item['customizable_options'] ?? null;
125+
126+
if ($customizableOptions === null) { // Update only item's qty
127+
$this->updateItemQty($itemId, $cart, $qty);
128+
} else { // Update customizable options (and QTY if changed)
129+
$this->updateCartItem->execute($cart, $itemId, $qty, $customizableOptions);
130+
$this->quoteRepository->save($cart);
131+
}
115132
}
116133
}
117134
}
135+
136+
/**
137+
* Updates item qty for the specified cart
138+
*
139+
* @param int $itemId
140+
* @param Quote $cart
141+
* @param float $qty
142+
* @throws GraphQlNoSuchEntityException
143+
* @throws NoSuchEntityException
144+
* @throws GraphQlNoSuchEntityException
145+
*/
146+
private function updateItemQty(int $itemId, Quote $cart, float $qty)
147+
{
148+
$cartItem = $cart->getItemById($itemId);
149+
if ($cartItem === false) {
150+
throw new GraphQlNoSuchEntityException(
151+
__('Could not find cart item with id: %1.', $itemId)
152+
);
153+
}
154+
$cartItem->setQty($qty);
155+
$this->cartItemRepository->save($cartItem);
156+
}
118157
}

app/code/Magento/QuoteGraphQl/etc/schema.graphqls

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ input UpdateCartItemsInput {
6767

6868
input CartItemQuantityInput {
6969
cart_item_id: Int!
70-
quantity: Float!
70+
quantity: Float
71+
customizable_options: [CustomizableOptionInput!]
7172
}
7273

7374
input RemoveItemFromCartInput {

0 commit comments

Comments
 (0)