Skip to content
This repository was archived by the owner on Dec 19, 2019. It is now read-only.

Commit eea5cdd

Browse files
author
Roman Glushko
committed
#141 Added add simple product to cart mutation to quote-graphql module
1 parent 4098a38 commit eea5cdd

File tree

8 files changed

+730
-1
lines changed

8 files changed

+730
-1
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\CatalogGraphQl\Model\Product\Option;
8+
9+
use Magento\Catalog\Model\Product\Option\Type\Date as ProductDateOptionType;
10+
use Magento\Framework\Stdlib\DateTime;
11+
12+
/**
13+
* Catalog product option date validator
14+
*/
15+
class DateType extends ProductDateOptionType
16+
{
17+
/**
18+
* {@inheritdoc}
19+
*/
20+
public function validateUserValue($values)
21+
{
22+
if ($this->_dateExists() || $this->_timeExists()) {
23+
return parent::validateUserValue($this->formatValues($values));
24+
}
25+
26+
return $this;
27+
}
28+
29+
/**
30+
* @param array $values
31+
* @return array mixed
32+
*/
33+
protected function formatValues($values)
34+
{
35+
if (isset($values[$this->getOption()->getId()])) {
36+
$value = $values[$this->getOption()->getId()];
37+
$dateTime = \DateTime::createFromFormat(DateTime::DATETIME_PHP_FORMAT, $value);
38+
$values[$this->getOption()->getId()] = [
39+
'date' => $value,
40+
'year' => $dateTime->format('Y'),
41+
'month' => $dateTime->format('m'),
42+
'day' => $dateTime->format('d'),
43+
'hour' => $dateTime->format('H'),
44+
'minute' => $dateTime->format('i'),
45+
'day_part' => $dateTime->format('a'),
46+
];
47+
}
48+
49+
return $values;
50+
}
51+
52+
/**
53+
* @return bool
54+
*/
55+
public function useCalendar()
56+
{
57+
return false;
58+
}
59+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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\Hydrator;
9+
10+
use Magento\Quote\Api\Data\CartInterface;
11+
use Magento\Quote\Model\Quote;
12+
use Magento\Quote\Model\Quote\Item as QuoteItem;
13+
14+
/**
15+
* {@inheritdoc}
16+
*/
17+
class CartHydrator
18+
{
19+
/**
20+
* @param CartInterface|Quote $cart
21+
*
22+
* @return array
23+
*/
24+
public function hydrate(CartInterface $cart): array
25+
{
26+
$items = [];
27+
28+
/**
29+
* @var QuoteItem $cartItem
30+
*/
31+
foreach ($cart->getAllItems() as $cartItem) {
32+
$productData = $cartItem->getProduct()->getData();
33+
$productData['model'] = $cartItem->getProduct();
34+
35+
$items[] = [
36+
'id' => $cartItem->getItemId(),
37+
'qty' => $cartItem->getQty(),
38+
'product' => $productData,
39+
'model' => $cartItem,
40+
];
41+
}
42+
43+
return [
44+
'items' => $items,
45+
];
46+
}
47+
}
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
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\Resolver\Cart;
9+
10+
use Magento\Authorization\Model\UserContextInterface;
11+
use Magento\Catalog\Api\ProductRepositoryInterface;
12+
use Magento\Framework\DataObject;
13+
use Magento\Framework\DataObjectFactory;
14+
use Magento\Framework\Exception\LocalizedException;
15+
use Magento\Framework\Exception\NoSuchEntityException;
16+
use Magento\Framework\GraphQl\Config\Element\Field;
17+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
18+
use Magento\Framework\GraphQl\Query\Resolver\Value;
19+
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
20+
use Magento\Framework\GraphQl\Query\ResolverInterface;
21+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
22+
use Magento\Framework\Message\AbstractMessage;
23+
use Magento\Framework\Stdlib\ArrayManager;
24+
use Magento\Quote\Api\CartRepositoryInterface;
25+
use Magento\Quote\Api\Data\CartInterface;
26+
use Magento\Quote\Api\GuestCartRepositoryInterface;
27+
use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface;
28+
use Magento\Quote\Model\Quote;
29+
use Magento\QuoteGraphQl\Model\Hydrator\CartHydrator;
30+
31+
/**
32+
* {@inheritdoc}
33+
*/
34+
class AddSimpleProductsToCart implements ResolverInterface
35+
{
36+
/**
37+
* @var CartRepositoryInterface
38+
*/
39+
private $cartRepository;
40+
41+
/**
42+
* @var MaskedQuoteIdToQuoteIdInterface
43+
*/
44+
private $maskedQuoteIdToQuoteId;
45+
46+
/**
47+
* @var DataObjectFactory
48+
*/
49+
private $dataObjectFactory;
50+
51+
/**
52+
* @var GuestCartRepositoryInterface
53+
*/
54+
private $guestCartRepository;
55+
56+
/**
57+
* @var ProductRepositoryInterface
58+
*/
59+
private $productRepository;
60+
61+
/**
62+
* @var CartHydrator
63+
*/
64+
private $cartHydrator;
65+
66+
/**
67+
* @var ArrayManager
68+
*/
69+
private $arrayManager;
70+
71+
/**
72+
* @var ValueFactory
73+
*/
74+
private $valueFactory;
75+
76+
/**
77+
* @var UserContextInterface
78+
*/
79+
private $userContext;
80+
81+
/**
82+
* @param DataObjectFactory $dataObjectFactory
83+
* @param CartHydrator $cartHydrator
84+
* @param ArrayManager $arrayManager
85+
* @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId
86+
* @param CartRepositoryInterface $cartRepository
87+
* @param GuestCartRepositoryInterface $guestCartRepository
88+
* @param ProductRepositoryInterface $productRepository
89+
* @param ValueFactory $valueFactory
90+
* @param UserContextInterface $userContext
91+
*/
92+
public function __construct(
93+
DataObjectFactory $dataObjectFactory,
94+
CartHydrator $cartHydrator,
95+
ArrayManager $arrayManager,
96+
MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId,
97+
CartRepositoryInterface $cartRepository,
98+
GuestCartRepositoryInterface $guestCartRepository,
99+
ProductRepositoryInterface $productRepository,
100+
ValueFactory $valueFactory,
101+
UserContextInterface $userContext
102+
) {
103+
$this->valueFactory = $valueFactory;
104+
$this->userContext = $userContext;
105+
$this->arrayManager = $arrayManager;
106+
$this->productRepository = $productRepository;
107+
$this->cartHydrator = $cartHydrator;
108+
$this->guestCartRepository = $guestCartRepository;
109+
$this->dataObjectFactory = $dataObjectFactory;
110+
$this->cartRepository = $cartRepository;
111+
$this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId;
112+
}
113+
114+
/**
115+
* {@inheritDoc}
116+
*/
117+
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) : Value
118+
{
119+
$cartHash = $this->arrayManager->get('input/cart_id', $args);
120+
$cartItems = $this->arrayManager->get('input/cartItems', $args);
121+
122+
if (!isset($cartHash)) {
123+
throw new GraphQlInputException(
124+
__('Missing key %1 in cart data', ['cart_id'])
125+
);
126+
}
127+
128+
if (!isset($cartItems)) {
129+
throw new GraphQlInputException(
130+
__('Missing key %1 in cart data', ['cartItems'])
131+
);
132+
}
133+
134+
$cart = $this->getCart((string) $cartHash);
135+
136+
foreach ($cartItems as $cartItem) {
137+
$sku = $this->arrayManager->get('details/sku', $cartItem);
138+
$product = $this->productRepository->get($sku);
139+
140+
$message = $cart->addProduct($product, $this->getBuyRequest($cartItem));
141+
142+
if (is_string($message)) {
143+
throw new GraphQlInputException(
144+
__('%1: %2', $sku, $message)
145+
);
146+
}
147+
148+
if ($cart->getData('has_error')) {
149+
throw new GraphQlInputException(
150+
__('%1: %2', $sku, $this->getCartErrors($cart))
151+
);
152+
}
153+
}
154+
155+
$this->cartRepository->save($cart);
156+
157+
$result = function () use ($cart) {
158+
return [
159+
'cart' => $this->cartHydrator->hydrate($cart)
160+
];
161+
};
162+
163+
return $this->valueFactory->create($result);
164+
}
165+
166+
/**
167+
* Format GraphQl input data to a shape that buy request has
168+
*
169+
* @param array $cartItem
170+
* @return DataObject
171+
*/
172+
private function getBuyRequest($cartItem): DataObject
173+
{
174+
$customOptions = [];
175+
$qty = $this->arrayManager->get('details/qty', $cartItem);
176+
$customizableOptions = $this->arrayManager->get('customizable_options', $cartItem, []);
177+
178+
foreach ($customizableOptions as $customizableOption) {
179+
$customOptions[$customizableOption['id']] = $customizableOption['value'];
180+
}
181+
182+
return $this->dataObjectFactory->create([
183+
'data' => [
184+
'qty' => $qty,
185+
'options' => $customOptions
186+
]
187+
]);
188+
}
189+
190+
/**
191+
* Collecting cart errors
192+
*
193+
* @param CartInterface|Quote $cart
194+
* @return string
195+
*/
196+
private function getCartErrors($cart): string
197+
{
198+
$errorMessages = [];
199+
200+
/** @var AbstractMessage $error */
201+
foreach ($cart->getErrors() as $error) {
202+
$errorMessages[] = $error->getText();
203+
}
204+
205+
return implode(PHP_EOL, $errorMessages);
206+
}
207+
208+
/**
209+
* Retrieving quote mode based on customer authorization
210+
*
211+
* @param string $cartHash
212+
* @return CartInterface|Quote
213+
* @throws NoSuchEntityException
214+
*/
215+
private function getCart(string $cartHash): CartInterface
216+
{
217+
$customerId = $this->userContext->getUserId();
218+
219+
if (!$customerId) {
220+
return $this->guestCartRepository->get($cartHash);
221+
}
222+
223+
$cartId = $this->maskedQuoteIdToQuoteId->execute((string) $cartHash);
224+
return $this->cartRepository->get($cartId);
225+
}
226+
}

0 commit comments

Comments
 (0)