Skip to content
This repository was archived by the owner on Dec 19, 2019. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion app/code/Magento/QuoteGraphQl/Model/Cart/ExtractDataFromCart.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,36 @@

namespace Magento\QuoteGraphQl\Model\Cart;

use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Quote\Model\Quote;
use Magento\Quote\Model\Quote\Item as QuoteItem;
use Magento\Quote\Model\QuoteIdToMaskedQuoteIdInterface;

/**
* Extract data from cart
*/
class ExtractDataFromCart
{
/**
* @var QuoteIdToMaskedQuoteIdInterface
*/
private $quoteIdToMaskedQuoteId;

/**
* @param QuoteIdToMaskedQuoteIdInterface $quoteIdToMaskedQuoteId
*/
public function __construct(
QuoteIdToMaskedQuoteIdInterface $quoteIdToMaskedQuoteId
) {
$this->quoteIdToMaskedQuoteId = $quoteIdToMaskedQuoteId;
}

/**
* Extract data from cart
*
* @param Quote $cart
* @return array
* @throws NoSuchEntityException
*/
public function execute(Quote $cart): array
{
Expand All @@ -41,7 +58,8 @@ public function execute(Quote $cart): array
}

return [
'items' => $items,
'cart_id' => $this->quoteIdToMaskedQuoteId->execute((int)$cart->getId()),
'items' => $items
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\QuoteGraphQl\Model\Resolver;

use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\Stdlib\ArrayManager;
use Magento\QuoteGraphQl\Model\Cart\AddProductsToCart;
use Magento\QuoteGraphQl\Model\Cart\ExtractDataFromCart;
use Magento\QuoteGraphQl\Model\Cart\GetCartForUser;

/**
* Add virtual products to cart GraphQl resolver
*
* {@inheritdoc}
*/
class AddVirtualProductsToCart implements ResolverInterface
{
/**
* @var ArrayManager
*/
private $arrayManager;

/**
* @var GetCartForUser
*/
private $getCartForUser;

/**
* @var AddProductsToCart
*/
private $addProductsToCart;

/**
* @var ExtractDataFromCart
*/
private $extractDataFromCart;

/**
* @param ArrayManager $arrayManager
* @param GetCartForUser $getCartForUser
* @param AddProductsToCart $addProductsToCart
* @param ExtractDataFromCart $extractDataFromCart
*/
public function __construct(
ArrayManager $arrayManager,
GetCartForUser $getCartForUser,
AddProductsToCart $addProductsToCart,
ExtractDataFromCart $extractDataFromCart
) {
$this->arrayManager = $arrayManager;
$this->getCartForUser = $getCartForUser;
$this->addProductsToCart = $addProductsToCart;
$this->extractDataFromCart = $extractDataFromCart;
}

/**
* @inheritdoc
*/
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
{
$cartHash = $this->arrayManager->get('input/cart_id', $args);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are not going to use the resolver for virtual/simple products, should we add an additional check for the product type in a resolver?
Currently we can add simple product via virtual product mutation and vice versa

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to have 2 different resolvers with checking of product type, but all general logic should be moved to Model in a separate class

Also, need to cover functionality with API-functional tests (including negative scenarios with a wrong product type)
Thanks

$cartItems = $this->arrayManager->get('input/cartItems', $args);

if (!isset($cartHash)) {
throw new GraphQlInputException(__('Missing key "cart_id" in cart data'));
}

if (!isset($cartItems) || !is_array($cartItems) || empty($cartItems)) {
throw new GraphQlInputException(__('Missing key "cartItems" in cart data'));
}

$currentUserId = $context->getUserId();
$cart = $this->getCartForUser->execute((string)$cartHash, $currentUserId);

$this->addProductsToCart->execute($cart, $cartItems);
$cartData = $this->extractDataFromCart->execute($cart);

return [
'cart' => $cartData,
];
}
}
1 change: 1 addition & 0 deletions app/code/Magento/QuoteGraphQl/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<arguments>
<argument name="supportedTypes" xsi:type="array">
<item name="simple" xsi:type="string">SimpleCartItem</item>
<item name="virtual" xsi:type="string">VirtualCartItem</item>
</argument>
</arguments>
</type>
Expand Down
19 changes: 19 additions & 0 deletions app/code/Magento/QuoteGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type Mutation {
setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput
setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetShippingMethodsOnCart")
addSimpleProductsToCart(input: AddSimpleProductsToCartInput): AddSimpleProductsToCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\AddSimpleProductsToCart")
addVirtualProductsToCart(input: AddVirtualProductsToCartInput): AddVirtualProductsToCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\AddVirtualProductsToCart")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we reuse resolver from addSimpleProductsToCart (rename in order to have a more universal name) here? Resolvers for simple and virtual products are identical.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we need to reuse configurable for simple because the code is the same (and we will have copy paste detector fail)

}

input SetShippingAddressesOnCartInput {
Expand Down Expand Up @@ -167,11 +168,21 @@ input AddSimpleProductsToCartInput {
cartItems: [SimpleProductCartItemInput!]!
}

input AddVirtualProductsToCartInput {
cart_id: String!
cartItems: [VirtualProductCartItemInput!]!
}

input SimpleProductCartItemInput {
data: CartItemInput!
customizable_options:[CustomizableOptionInput!]
}

input VirtualProductCartItemInput {
data: CartItemInput!
customizable_options:[CustomizableOptionInput!]
}

input CustomizableOptionInput {
id: Int!
value: String!
Expand All @@ -181,10 +192,18 @@ type AddSimpleProductsToCartOutput {
cart: Cart!
}

type AddVirtualProductsToCartOutput {
cart: Cart!
}

type SimpleCartItem implements CartItemInterface @doc(description: "Simple Cart Item") {
customizable_options: [SelectedCustomizableOption] @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\CustomizableOptions")
}

type VirtualCartItem implements CartItemInterface @doc(description: "Virtual Cart Item") {
customizable_options: [SelectedCustomizableOption] @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\CustomizableOptions")
}

input CartItemInput {
sku: String!
qty: Float!
Expand Down