Skip to content

Commit f1ee8ba

Browse files
ENGCOM-4790: magento/graphql-ce#607: Expanded 'createdEmptyCart' mutation with not… #610
- Merge Pull Request magento/graphql-ce#610 from anzin/graphql-ce:magento2/graphql-ce_expand_createEmptyCart_mutation - Merged commits: 1. b82d771 2. 38f473c 3. 9009ccc 4. a6cb829
2 parents a48a507 + a6cb829 commit f1ee8ba

File tree

7 files changed

+336
-91
lines changed

7 files changed

+336
-91
lines changed

app/code/Magento/Quote/Model/QuoteIdMask.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,14 @@ protected function _construct()
5353
* Initialize quote identifier before save
5454
*
5555
* @return $this
56+
* @throws \Magento\Framework\Exception\LocalizedException
5657
*/
5758
public function beforeSave()
5859
{
5960
parent::beforeSave();
60-
$this->setMaskedId($this->randomDataGenerator->getUniqueHash());
61+
if (empty($this->getMaskedId())) {
62+
$this->setMaskedId($this->randomDataGenerator->getUniqueHash());
63+
}
6164
return $this;
6265
}
6366
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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\Quote\Api\CartManagementInterface;
11+
use Magento\Quote\Model\QuoteIdMaskFactory;
12+
use Magento\Quote\Model\ResourceModel\Quote\QuoteIdMask as QuoteIdMaskResourceModel;
13+
14+
/**
15+
* Create empty cart for customer
16+
*/
17+
class CreateEmptyCartForCustomer
18+
{
19+
/**
20+
* @var CartManagementInterface
21+
*/
22+
private $cartManagement;
23+
24+
/**
25+
* @var QuoteIdMaskFactory
26+
*/
27+
private $quoteIdMaskFactory;
28+
29+
/**
30+
* @var QuoteIdMaskResourceModel
31+
*/
32+
private $quoteIdMaskResourceModel;
33+
34+
/**
35+
* @param CartManagementInterface $cartManagement
36+
* @param QuoteIdMaskFactory $quoteIdMaskFactory
37+
* @param QuoteIdMaskResourceModel $quoteIdMaskResourceModel
38+
*/
39+
public function __construct(
40+
CartManagementInterface $cartManagement,
41+
QuoteIdMaskFactory $quoteIdMaskFactory,
42+
QuoteIdMaskResourceModel $quoteIdMaskResourceModel
43+
) {
44+
$this->cartManagement = $cartManagement;
45+
$this->quoteIdMaskFactory = $quoteIdMaskFactory;
46+
$this->quoteIdMaskResourceModel = $quoteIdMaskResourceModel;
47+
}
48+
49+
/**
50+
* @param string|null $predefinedMaskedQuoteId
51+
* @return string
52+
*/
53+
public function execute(int $customerId, string $predefinedMaskedQuoteId = null): string
54+
{
55+
$quoteId = $this->cartManagement->createEmptyCartForCustomer($customerId);
56+
57+
$quoteIdMask = $this->quoteIdMaskFactory->create();
58+
$quoteIdMask->setQuoteId($quoteId);
59+
60+
if (isset($predefinedMaskedQuoteId)) {
61+
$quoteIdMask->setMaskedId($predefinedMaskedQuoteId);
62+
}
63+
64+
$this->quoteIdMaskResourceModel->save($quoteIdMask);
65+
return $quoteIdMask->getMaskedId();
66+
}
67+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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\Quote\Api\GuestCartManagementInterface;
11+
use Magento\Quote\Model\QuoteIdMaskFactory;
12+
use Magento\Quote\Model\ResourceModel\Quote\QuoteIdMask as QuoteIdMaskResourceModel;
13+
14+
/**
15+
* Create empty cart for guest
16+
*/
17+
class CreateEmptyCartForGuest
18+
{
19+
/**
20+
* @var GuestCartManagementInterface
21+
*/
22+
private $guestCartManagement;
23+
24+
/**
25+
* @var QuoteIdMaskFactory
26+
*/
27+
private $quoteIdMaskFactory;
28+
29+
/**
30+
* @var QuoteIdMaskResourceModel
31+
*/
32+
private $quoteIdMaskResourceModel;
33+
34+
/**
35+
* @param GuestCartManagementInterface $guestCartManagement
36+
* @param QuoteIdMaskFactory $quoteIdMaskFactory
37+
* @param QuoteIdMaskResourceModel $quoteIdMaskResourceModel
38+
*/
39+
public function __construct(
40+
GuestCartManagementInterface $guestCartManagement,
41+
QuoteIdMaskFactory $quoteIdMaskFactory,
42+
QuoteIdMaskResourceModel $quoteIdMaskResourceModel
43+
) {
44+
$this->guestCartManagement = $guestCartManagement;
45+
$this->quoteIdMaskFactory = $quoteIdMaskFactory;
46+
$this->quoteIdMaskResourceModel = $quoteIdMaskResourceModel;
47+
}
48+
49+
/**
50+
* @param string|null $predefinedMaskedQuoteId
51+
* @return string
52+
*/
53+
public function execute(string $predefinedMaskedQuoteId = null): string
54+
{
55+
$maskedQuoteId = $this->guestCartManagement->createEmptyCart();
56+
57+
if (isset($predefinedMaskedQuoteId)) {
58+
$quoteIdMask = $this->quoteIdMaskFactory->create();
59+
$this->quoteIdMaskResourceModel->load($quoteIdMask, $maskedQuoteId, 'masked_id');
60+
61+
$quoteIdMask->setMaskedId($predefinedMaskedQuoteId);
62+
$this->quoteIdMaskResourceModel->save($quoteIdMask);
63+
}
64+
return $predefinedMaskedQuoteId ?? $maskedQuoteId;
65+
}
66+
}

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

Lines changed: 58 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,55 +7,49 @@
77

88
namespace Magento\QuoteGraphQl\Model\Resolver;
99

10+
use Magento\Framework\Exception\NoSuchEntityException;
1011
use Magento\Framework\GraphQl\Config\Element\Field;
12+
use Magento\Framework\GraphQl\Exception\GraphQlAlreadyExistsException;
13+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
1114
use Magento\Framework\GraphQl\Query\ResolverInterface;
1215
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
13-
use Magento\Quote\Api\CartManagementInterface;
14-
use Magento\Quote\Api\GuestCartManagementInterface;
15-
use Magento\Quote\Model\QuoteIdToMaskedQuoteIdInterface;
16-
use Magento\Quote\Model\QuoteIdMaskFactory;
16+
use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface;
17+
use Magento\QuoteGraphQl\Model\Cart\CreateEmptyCartForCustomer;
18+
use Magento\QuoteGraphQl\Model\Cart\CreateEmptyCartForGuest;
1719

1820
/**
1921
* @inheritdoc
2022
*/
2123
class CreateEmptyCart implements ResolverInterface
2224
{
2325
/**
24-
* @var CartManagementInterface
26+
* @var CreateEmptyCartForCustomer
2527
*/
26-
private $cartManagement;
28+
private $createEmptyCartForCustomer;
2729

2830
/**
29-
* @var GuestCartManagementInterface
31+
* @var CreateEmptyCartForGuest
3032
*/
31-
private $guestCartManagement;
33+
private $createEmptyCartForGuest;
3234

3335
/**
34-
* @var QuoteIdToMaskedQuoteIdInterface
36+
* @var MaskedQuoteIdToQuoteIdInterface
3537
*/
36-
private $quoteIdToMaskedId;
38+
private $maskedQuoteIdToQuoteId;
3739

3840
/**
39-
* @var QuoteIdMaskFactory
40-
*/
41-
private $quoteIdMaskFactory;
42-
43-
/**
44-
* @param CartManagementInterface $cartManagement
45-
* @param GuestCartManagementInterface $guestCartManagement
46-
* @param QuoteIdToMaskedQuoteIdInterface $quoteIdToMaskedId
47-
* @param QuoteIdMaskFactory $quoteIdMaskFactory
41+
* @param CreateEmptyCartForCustomer $createEmptyCartForCustomer
42+
* @param CreateEmptyCartForGuest $createEmptyCartForGuest
43+
* @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId
4844
*/
4945
public function __construct(
50-
CartManagementInterface $cartManagement,
51-
GuestCartManagementInterface $guestCartManagement,
52-
QuoteIdToMaskedQuoteIdInterface $quoteIdToMaskedId,
53-
QuoteIdMaskFactory $quoteIdMaskFactory
46+
CreateEmptyCartForCustomer $createEmptyCartForCustomer,
47+
CreateEmptyCartForGuest $createEmptyCartForGuest,
48+
MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId
5449
) {
55-
$this->cartManagement = $cartManagement;
56-
$this->guestCartManagement = $guestCartManagement;
57-
$this->quoteIdToMaskedId = $quoteIdToMaskedId;
58-
$this->quoteIdMaskFactory = $quoteIdMaskFactory;
50+
$this->createEmptyCartForCustomer = $createEmptyCartForCustomer;
51+
$this->createEmptyCartForGuest = $createEmptyCartForGuest;
52+
$this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId;
5953
}
6054

6155
/**
@@ -65,19 +59,45 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
6559
{
6660
$customerId = $context->getUserId();
6761

68-
if (0 !== $customerId && null !== $customerId) {
69-
$quoteId = $this->cartManagement->createEmptyCartForCustomer($customerId);
70-
$maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$quoteId);
71-
72-
if (empty($maskedQuoteId)) {
73-
$quoteIdMask = $this->quoteIdMaskFactory->create();
74-
$quoteIdMask->setQuoteId($quoteId)->save();
75-
$maskedQuoteId = $quoteIdMask->getMaskedId();
76-
}
77-
} else {
78-
$maskedQuoteId = $this->guestCartManagement->createEmptyCart();
62+
$predefinedMaskedQuoteId = null;
63+
if (isset($args['input']['cart_id'])) {
64+
$predefinedMaskedQuoteId = $args['input']['cart_id'];
65+
$this->validateMaskedId($predefinedMaskedQuoteId);
7966
}
8067

68+
$maskedQuoteId = (0 === $customerId || null === $customerId)
69+
? $this->createEmptyCartForGuest->execute($predefinedMaskedQuoteId)
70+
: $this->createEmptyCartForCustomer->execute($customerId, $predefinedMaskedQuoteId);
8171
return $maskedQuoteId;
8272
}
73+
74+
/**
75+
* @param string $maskedId
76+
* @throws GraphQlAlreadyExistsException
77+
* @throws GraphQlInputException
78+
*/
79+
private function validateMaskedId(string $maskedId): void
80+
{
81+
if (mb_strlen($maskedId) != 32) {
82+
throw new GraphQlInputException(__('Cart ID length should to be 32 symbols.'));
83+
}
84+
85+
if ($this->isQuoteWithSuchMaskedIdAlreadyExists($maskedId)) {
86+
throw new GraphQlAlreadyExistsException(__('Cart with ID "%1" already exists.', $maskedId));
87+
}
88+
}
89+
90+
/**
91+
* @param string $maskedId
92+
* @return bool
93+
*/
94+
private function isQuoteWithSuchMaskedIdAlreadyExists(string $maskedId): bool
95+
{
96+
try {
97+
$this->maskedQuoteIdToQuoteId->execute($maskedId);
98+
return true;
99+
} catch (NoSuchEntityException $e) {
100+
return false;
101+
}
102+
}
83103
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ type Query {
66
}
77

88
type Mutation {
9-
createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CreateEmptyCart") @doc(description:"Creates an empty shopping cart for a guest or logged in user")
9+
createEmptyCart(input: createEmptyCartInput): String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CreateEmptyCart") @doc(description:"Creates an empty shopping cart for a guest or logged in user")
1010
addSimpleProductsToCart(input: AddSimpleProductsToCartInput): AddSimpleProductsToCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\AddSimpleProductsToCart")
1111
addVirtualProductsToCart(input: AddVirtualProductsToCartInput): AddVirtualProductsToCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\AddSimpleProductsToCart")
1212
applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ApplyCouponToCart")
@@ -21,6 +21,10 @@ type Mutation {
2121
placeOrder(input: PlaceOrderInput): PlaceOrderOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\PlaceOrder")
2222
}
2323

24+
input createEmptyCartInput {
25+
cart_id: String
26+
}
27+
2428
input AddSimpleProductsToCartInput {
2529
cart_id: String!
2630
cartItems: [SimpleProductCartItemInput!]!

0 commit comments

Comments
 (0)