Skip to content

Commit

Permalink
Merge pull request #4948 from magento-engcom/2.3-develop-graphql-dail…
Browse files Browse the repository at this point in the history
…y-prs

- Community Contributions - GraphQL daily delivery
  • Loading branch information
irenelagno authored Nov 1, 2019
2 parents edec48a + 59aa830 commit dac1ea5
Show file tree
Hide file tree
Showing 19 changed files with 855 additions and 14 deletions.
145 changes: 145 additions & 0 deletions app/code/Magento/BundleGraphQl/Model/Cart/BundleOptionDataProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\BundleGraphQl\Model\Cart;

use Magento\Bundle\Helper\Catalog\Product\Configuration;
use Magento\Catalog\Model\Product;
use Magento\Quote\Model\Quote\Item;
use Magento\Framework\Pricing\Helper\Data;
use Magento\Framework\Serialize\SerializerInterface;

/**
* Data provider for bundled product options
*/
class BundleOptionDataProvider
{
/**
* @var Data
*/
private $pricingHelper;

/**
* @var SerializerInterface
*/
private $serializer;

/**
* @var Configuration
*/
private $configuration;

/**
* @param Data $pricingHelper
* @param SerializerInterface $serializer
* @param Configuration $configuration
*/
public function __construct(
Data $pricingHelper,
SerializerInterface $serializer,
Configuration $configuration
) {
$this->pricingHelper = $pricingHelper;
$this->serializer = $serializer;
$this->configuration = $configuration;
}

/**
* Extract data for a bundled cart item
*
* @param Item $item
* @return array
*/
public function getData(Item $item): array
{
$options = [];
$product = $item->getProduct();

/** @var \Magento\Bundle\Model\Product\Type $typeInstance */
$typeInstance = $product->getTypeInstance();

$optionsQuoteItemOption = $item->getOptionByCode('bundle_option_ids');
$bundleOptionsIds = $optionsQuoteItemOption
? $this->serializer->unserialize($optionsQuoteItemOption->getValue())
: [];

if ($bundleOptionsIds) {
/** @var \Magento\Bundle\Model\ResourceModel\Option\Collection $optionsCollection */
$optionsCollection = $typeInstance->getOptionsByIds($bundleOptionsIds, $product);

$selectionsQuoteItemOption = $item->getOptionByCode('bundle_selection_ids');

$bundleSelectionIds = $this->serializer->unserialize($selectionsQuoteItemOption->getValue());

if (!empty($bundleSelectionIds)) {
$selectionsCollection = $typeInstance->getSelectionsByIds($bundleSelectionIds, $product);
$bundleOptions = $optionsCollection->appendSelections($selectionsCollection, true);

$options = $this->buildBundleOptions($bundleOptions, $item);
}
}

return $options;
}

/**
* Build bundle product options based on current selection
*
* @param \Magento\Bundle\Model\Option[] $bundleOptions
* @param Item $item
* @return array
*/
private function buildBundleOptions(array $bundleOptions, Item $item): array
{
$options = [];
foreach ($bundleOptions as $bundleOption) {
if (!$bundleOption->getSelections()) {
continue;
}

$options[] = [
'id' => $bundleOption->getId(),
'label' => $bundleOption->getTitle(),
'type' => $bundleOption->getType(),
'values' => $this->buildBundleOptionValues($bundleOption->getSelections(), $item),
];
}

return $options;
}

/**
* Build bundle product option values based on current selection
*
* @param Product[] $selections
* @param Item $item
* @return array
*/
private function buildBundleOptionValues(array $selections, Item $item): array
{
$values = [];

$product = $item->getProduct();
foreach ($selections as $selection) {
$qty = (float) $this->configuration->getSelectionQty($product, $selection->getSelectionId());
if (!$qty) {
continue;
}

$selectionPrice = $this->configuration->getSelectionFinalPrice($item, $selection);

$values[] = [
'id' => $selection->getSelectionId(),
'label' => $selection->getName(),
'quantity' => $qty,
'price' => $this->pricingHelper->currency($selectionPrice, false, false),
];
}

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

namespace Magento\BundleGraphQl\Model\Cart\BuyRequest;

use Magento\Framework\Stdlib\ArrayManager;
use Magento\QuoteGraphQl\Model\Cart\BuyRequest\BuyRequestDataProviderInterface;

/**
* Data provider for bundle product buy requests
*/
class BundleDataProvider implements BuyRequestDataProviderInterface
{
/**
* @var ArrayManager
*/
private $arrayManager;

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

/**
* @inheritdoc
*/
public function execute(array $cartItemData): array
{
$bundleOptions = [];
$bundleInputs = $this->arrayManager->get('bundle_options', $cartItemData) ?? [];
foreach ($bundleInputs as $bundleInput) {
$bundleOptions['bundle_option'][$bundleInput['id']] = $bundleInput['value'];
$bundleOptions['bundle_option_qty'][$bundleInput['id']] = $bundleInput['quantity'];
}

return $bundleOptions;
}
}
46 changes: 46 additions & 0 deletions app/code/Magento/BundleGraphQl/Model/Resolver/BundleOption.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\BundleGraphQl\Model\Resolver;

use Magento\BundleGraphQl\Model\Cart\BundleOptionDataProvider;
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;

/**
* Resolver for bundle product options
*/
class BundleOption implements ResolverInterface
{
/**
* @var BundleOptionDataProvider
*/
private $dataProvider;

/**
* @param BundleOptionDataProvider $bundleOptionDataProvider
*/
public function __construct(
BundleOptionDataProvider $bundleOptionDataProvider
) {
$this->dataProvider = $bundleOptionDataProvider;
}

/**
* @inheritdoc
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
{
if (!isset($value['model'])) {
throw new GraphQlInputException(__('Value must contain "model" property.'));
}
return $this->dataProvider->getData($value['model']);
}
}
2 changes: 2 additions & 0 deletions app/code/Magento/BundleGraphQl/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
"magento/module-catalog": "*",
"magento/module-bundle": "*",
"magento/module-catalog-graph-ql": "*",
"magento/module-quote": "*",
"magento/module-quote-graph-ql": "*",
"magento/module-store": "*",
"magento/framework": "*"
},
Expand Down
7 changes: 7 additions & 0 deletions app/code/Magento/BundleGraphQl/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,11 @@
</argument>
</arguments>
</type>
<type name="Magento\QuoteGraphQl\Model\Resolver\CartItemTypeResolver">
<arguments>
<argument name="supportedTypes" xsi:type="array">
<item name="bundle" xsi:type="string">BundleCartItem</item>
</argument>
</arguments>
</type>
</config>
7 changes: 7 additions & 0 deletions app/code/Magento/BundleGraphQl/etc/graphql/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
</argument>
</arguments>
</type>
<type name="Magento\QuoteGraphQl\Model\Cart\BuyRequest\BuyRequestBuilder">
<arguments>
<argument name="providers" xsi:type="array">
<item name="bundle" xsi:type="object">Magento\BundleGraphQl\Model\Cart\BuyRequest\BundleDataProvider</item>
</argument>
</arguments>
</type>
<type name="Magento\Framework\GraphQl\Schema\Type\Enum\DefaultDataMapper">
<arguments>
<argument name="map" xsi:type="array">
Expand Down
1 change: 1 addition & 0 deletions app/code/Magento/BundleGraphQl/etc/module.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Magento_BundleGraphQl" >
<sequence>
<module name="Magento_QuoteGraphQl"/>
<module name="Magento_Catalog"/>
<module name="Magento_BundleProduct"/>
<module name="Magento_Store"/>
Expand Down
44 changes: 44 additions & 0 deletions app/code/Magento/BundleGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
@@ -1,6 +1,50 @@
# Copyright © Magento, Inc. All rights reserved.
# See COPYING.txt for license details.

type Mutation {
addBundleProductsToCart(input: AddBundleProductsToCartInput): AddBundleProductsToCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\AddSimpleProductsToCart")
}

input AddBundleProductsToCartInput {
cart_id: String!
cart_items: [BundleProductCartItemInput!]!
}

input BundleProductCartItemInput {
data: CartItemInput!
bundle_options:[BundleOptionInput!]!
customizable_options:[CustomizableOptionInput!]
}

input BundleOptionInput {
id: Int!
quantity: Float!
value: [String!]!
}

type AddBundleProductsToCartOutput {
cart: Cart!
}

type BundleCartItem implements CartItemInterface {
customizable_options: [SelectedCustomizableOption]! @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\CustomizableOptions")
bundle_options: [SelectedBundleOption!]! @resolver(class: "Magento\\BundleGraphQl\\Model\\Resolver\\BundleOption")
}

type SelectedBundleOption {
id: Int!
label: String!
type: String!
values: [SelectedBundleOptionValue!]!
}

type SelectedBundleOptionValue {
id: Int!
label: String!
quantity: Float!
price: Float!
}

type BundleItem @doc(description: "BundleItem defines an individual item in a bundle product.") {
option_id: Int @doc(description: "An ID assigned to each type of item in a bundle product.")
title: String @doc(description: "The display name of the item.")
Expand Down
4 changes: 2 additions & 2 deletions app/code/Magento/DownloadableGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ type DownloadableProductLinks @doc(description: "DownloadableProductLinks define
sort_order: Int @doc(description: "A number indicating the sort order")
price: Float @doc(description: "The price of the downloadable product")
sample_url: String @doc(description: "URL to the downloadable sample")
is_shareable: Boolean @deprecated(reason: "This information shoud not be exposed on frontend")
number_of_downloads: Int @deprecated(reason: "This information shoud not be exposed on frontend")
is_shareable: Boolean @deprecated(reason: "This information should not be exposed on frontend")
number_of_downloads: Int @deprecated(reason: "This information should not be exposed on frontend")
link_type: DownloadableFileTypeEnum @deprecated(reason: "`sample_url` serves to get the downloadable sample")
sample_type: DownloadableFileTypeEnum @deprecated(reason: "`sample_url` serves to get the downloadable sample")
sample_file: String @deprecated(reason: "`sample_url` serves to get the downloadable sample")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
interface BuyRequestDataProviderInterface
{
/**
* Build buy request for adding product to cart
* Provide buy request data from add to cart item request
*
* @param array $cartItemData
* @return DataObject
* @return array
*/
public function execute(array $cartItemData): array;
}
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ private function processCartItems(Quote $cart, array $items): void
$itemId = (int)$item['cart_item_id'];
$customizableOptions = $item['customizable_options'] ?? [];

$cartItem = $cart->getItemById($itemId);
if ($cartItem && $cartItem->getParentItemId()) {
throw new GraphQlInputException(__('Child items may not be updated.'));
}

if (count($customizableOptions) === 0 && !isset($item['quantity'])) {
throw new GraphQlInputException(__('Required parameter "quantity" for "cart_items" is missing.'));
}
Expand Down
Loading

0 comments on commit dac1ea5

Please sign in to comment.