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

Commit

Permalink
#141 Added support of dropdown options
Browse files Browse the repository at this point in the history
  • Loading branch information
Roman Glushko committed Sep 2, 2018
1 parent cfa680a commit e9ae719
Show file tree
Hide file tree
Showing 6 changed files with 363 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ public function hydrate(CartInterface $cart): array
$items[] = [
'id' => $cartItem->getItemId(),
'qty' => $cartItem->getQty(),
'product' => $productData
'product' => $productData,
'model' => $cartItem,
];
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\QuoteGraphQl\Model\Resolver\CartItem;

use Magento\Authorization\Model\UserContextInterface;
use Magento\Catalog\Model\Product\Option\Type\DefaultType as DefaultOptionType;
use Magento\Catalog\Model\Product\Option\Type\Select as SelectOptionType;
use Magento\Catalog\Model\Product\Option\Type\Text as TextOptionType;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\Resolver\Value;
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Quote\Model\Quote\Item as QuoteItem;

/**
* {@inheritdoc}
*/
class CustomizableOptions implements ResolverInterface
{
/**
* @var ValueFactory
*/
private $valueFactory;

/**
* @var UserContextInterface
*/
private $userContext;

/**
* @param ValueFactory $valueFactory
* @param UserContextInterface $userContext
*/
public function __construct(
ValueFactory $valueFactory,
UserContextInterface $userContext
) {
$this->valueFactory = $valueFactory;
$this->userContext = $userContext;
}

/**
* {@inheritDoc}
*/
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) : Value
{
if (!isset($value['model'])) {
return $this->valueFactory->create(function () {
return [];
});
}

/** @var QuoteItem $cartItem */
$cartItem = $value['model'];
$optionIds = $cartItem->getOptionByCode('option_ids');

if (!$optionIds) {
return $this->valueFactory->create(function () {
return [];
});
}

$customOptions = [];
$customOptionIds = explode(',', $optionIds->getValue());

foreach ($customOptionIds as $optionId) {
$customOptionData = $this->getOptionData($cartItem, $optionId);

if (count($customOptionData) > 0) {
continue;
}

$customOptions[] = $customOptionData;
}

$result = function () use ($customOptions) {
return $customOptions;
};

return $this->valueFactory->create($result);
}

/**
* @param QuoteItem $cartItem
* @param int $optionId
* @return array
*/
private function getOptionData($cartItem, int $optionId): array
{
$product = $cartItem->getProduct();
$option = $product->getOptionById($optionId);

if (!$option) {
return [];
}

$itemOption = $cartItem->getOptionByCode('option_' . $option->getId());

/** @var SelectOptionType|TextOptionType|DefaultOptionType $optionTypeGroup */
$optionTypeGroup = $option->groupFactory($option->getType())
->setOption($option)
->setConfigurationItem($cartItem)
->setConfigurationItemOption($itemOption);

if ('file' == $option->getType()) {
$downloadParams = $cartItem->getFileDownloadParams();
if ($downloadParams) {
$url = $downloadParams->getUrl();
if ($url) {
$optionTypeGroup->setCustomOptionDownloadUrl($url);
}
$urlParams = $downloadParams->getUrlParams();
if ($urlParams) {
$optionTypeGroup->setCustomOptionUrlParams($urlParams);
}
}
}

$optionValue = $option->getValueById($itemOption->getValue());

return [
'id' => $option->getId(),
'label' => $option->getTitle(),
'type' => $option->getType(),
'values' => [
[
'id' => $optionValue->getId(),
'label' => $optionValue->getTitle(),
'sort_order' => $optionValue->getSortOrder(),
'price' => [
'type' => strtoupper($optionValue->getPriceType()),
'units' => '$',
'value' => $optionValue->getPrice(),
]
]
],
'sort_order' => $option->getSortOrder(),
];
}
}
27 changes: 24 additions & 3 deletions app/code/Magento/QuoteGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# See COPYING.txt for license details.

type Mutation {
createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user")
createEmptyCart: String @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\Cart\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user")
}

type Cart {
Expand All @@ -11,11 +11,32 @@ type Cart {

input CartItemDetailsInput {
sku: String!
quantity: Float!
qty: Float!
}

interface CartItemInterface @typeResolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\CartItemTypeResolverComposite") {
id: String! # Hashed cart item ID
id: String!
qty: Float!
product: ProductInterface!
}

type SelectedCustomizableOption {
id: Int!
label: String!
type: String!
values: [SelectedCustomizableOptionValue!]!
sort_order: Int!
}

type SelectedCustomizableOptionValue {
id: Int
label: String!
price: CartItemSelectedOptionValuePrice!
sort_order: Int!
}

type CartItemSelectedOptionValuePrice {
value: Float!
units: String!
type: PriceTypeEnum!
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@
*/
declare(strict_types=1);

namespace Magento\SimpleProductGraphQl\Model\Resolver\Product;
namespace Magento\SimpleProductGraphQl\Model\Resolver\Cart;

use Magento\Authorization\Model\UserContextInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\DataObject;
use Magento\Framework\DataObjectFactory;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Query\Resolver\Value;
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\Message\AbstractMessage;
use Magento\Framework\Stdlib\ArrayManager;
use Magento\Quote\Api\Data\CartInterface;
use Magento\Quote\Api\GuestCartRepositoryInterface;
Expand All @@ -27,6 +30,11 @@
*/
class AddSimpleProductsToCart implements ResolverInterface
{
/**
* @var DataObjectFactory
*/
private $dataObjectFactory;

/**
* @var GuestCartRepositoryInterface
*/
Expand Down Expand Up @@ -63,6 +71,7 @@ class AddSimpleProductsToCart implements ResolverInterface
private $userContext;

/**
* @param DataObjectFactory $dataObjectFactory
* @param CartHydrator $cartHydrator
* @param ArrayManager $arrayManager
* @param GuestCartRepositoryInterface $guestCartRepository
Expand All @@ -72,6 +81,7 @@ class AddSimpleProductsToCart implements ResolverInterface
* @param UserContextInterface $userContext
*/
public function __construct(
DataObjectFactory $dataObjectFactory,
CartHydrator $cartHydrator,
ArrayManager $arrayManager,
GuestCartRepositoryInterface $guestCartRepository,
Expand All @@ -87,6 +97,7 @@ public function __construct(
$this->cartHydrator = $cartHydrator;
$this->quoteRepository = $quoteRepository;
$this->guestCartRepository = $guestCartRepository;
$this->dataObjectFactory = $dataObjectFactory;
}

/**
Expand Down Expand Up @@ -116,20 +127,63 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value

foreach ($cartItems as $cartItem) {
$sku = $this->arrayManager->get('details/sku', $cartItem);
$qty = $this->arrayManager->get('details/quantity', $cartItem);
$product = $this->productRepository->get($sku);

$cart->addProduct($product, $qty);
$cart->addProduct($product, $this->getBuyRequest($cartItem));

if ($cart->getData('has_error')) {
throw new GraphQlInputException(__('Cart has an error: %1 (%2)', $this->getCartErrors($cart), $sku));
}
}

$this->quoteRepository->save($cart);

$result = function () use ($cart) {
return [
'cart' => $this->cartHydrator->hydrate($cart),
'cart' => $this->cartHydrator->hydrate($cart)
];
};

return $this->valueFactory->create($result);
}

/**
* @param array $cartItem
*
* @return DataObject
*/
private function getBuyRequest($cartItem): DataObject
{
$qty = $this->arrayManager->get('details/qty', $cartItem);
$customizableOptions = $this->arrayManager->get('customizable_options', $cartItem, []);
$customOptions = [];

foreach ($customizableOptions as $customizableOption) {
$customOptions[$customizableOption['id']] = $customizableOption['value'];
}

return $this->dataObjectFactory->create([
'data' => [
'qty' => $qty,
'options' => $customOptions
]
]);
}

/**
* @param CartInterface|Quote $cart
*
* @return string
*/
private function getCartErrors($cart): string
{
$errorMessages = [];

/** @var AbstractMessage $error */
foreach ($cart->getErrors() as $error) {
$errorMessages[] = $error->getText();
}

return implode(PHP_EOL, $errorMessages);
}
}
Loading

0 comments on commit e9ae719

Please sign in to comment.