Skip to content

[GraphQl][Wishlist] Implementing a new Query of getting customer wishlist #29148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all 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
144 changes: 144 additions & 0 deletions app/code/Magento/Bundle/Model/Product/BundleOptionDataProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Bundle\Model\Product;

use Magento\Bundle\Helper\Catalog\Product\Configuration;
use Magento\Bundle\Model\Option;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\Configuration\Item\ItemInterface;
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 item
*
* @param ItemInterface $item
*
* @return array
*/
public function getData(ItemInterface $item): array
{
$options = [];
$product = $item->getProduct();
$optionsQuoteItemOption = $item->getOptionByCode('bundle_option_ids');
$bundleOptionsIds = $optionsQuoteItemOption
? $this->serializer->unserialize($optionsQuoteItemOption->getValue())
: [];

/** @var Type $typeInstance */
$typeInstance = $product->getTypeInstance();

if ($bundleOptionsIds) {
$selectionsQuoteItemOption = $item->getOptionByCode('bundle_selection_ids');
$optionsCollection = $typeInstance->getOptionsByIds($bundleOptionsIds, $product);
$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 Option[] $bundleOptions
* @param ItemInterface $item
*
* @return array
*/
private function buildBundleOptions(array $bundleOptions, ItemInterface $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 ItemInterface $item
*
* @return array
*/
private function buildBundleOptionValues(array $selections, ItemInterface $item): array
{
$product = $item->getProduct();
$values = [];

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

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

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

namespace Magento\BundleGraphQl\Model\Wishlist;

use Magento\Bundle\Model\Product\BundleOptionDataProvider;
use Magento\Catalog\Model\Product\Configuration\Item\ItemInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

/**
* Fetches the selected bundle options
*/
class BundleOptions implements ResolverInterface
{
/**
* @var BundleOptionDataProvider
*/
private $bundleOptionDataProvider;

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

/**
* @inheritdoc
*/
public function resolve(
Field $field,
$context,
ResolveInfo $info,
array $value = null,
array $args = null
) {
if (!$value['itemModel'] instanceof ItemInterface) {
throw new LocalizedException(__('"itemModel" should be a "%instance" instance', [
'instance' => ItemInterface::class
]));
}

return $this->bundleOptionDataProvider->getData($value['itemModel']);
}
}
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 @@ -100,4 +100,11 @@
</argument>
</arguments>
</type>
<type name="Magento\WishlistGraphQl\Model\Resolver\Type\WishlistItemType">
<arguments>
<argument name="supportedTypes" xsi:type="array">
<item name="bundle" xsi:type="string">BundleWishlistItem</item>
</argument>
</arguments>
</type>
</config>
4 changes: 4 additions & 0 deletions app/code/Magento/BundleGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,7 @@ type ItemSelectedBundleOptionValue @doc(description: "A list of values for the s
quantity: Float! @doc(description: "Indicates how many of this bundle product were ordered")
price: Money! @doc(description: "The price of the child bundle product")
}

type BundleWishlistItem implements WishlistItemInterface {
bundle_options: [SelectedBundleOption!] @doc(description: "An array containing information about the selected bundle items") @resolver(class: "\\Magento\\BundleGraphQl\\Model\\Wishlist\\BundleOptions")
}
8 changes: 8 additions & 0 deletions app/code/Magento/CatalogGraphQl/etc/graphql/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -180,4 +180,12 @@
<argument name="templateFilterModel" xsi:type="string">Magento\Widget\Model\Template\FilterEmulate</argument>
</arguments>
</type>
<type name="Magento\WishlistGraphQl\Model\Resolver\Type\WishlistItemType">
<arguments>
<argument name="supportedTypes" xsi:type="array">
<item name="simple" xsi:type="string">SimpleWishlistItem</item>
<item name="virtual" xsi:type="string">VirtualWishlistItem</item>
</argument>
</arguments>
</type>
</config>
6 changes: 6 additions & 0 deletions app/code/Magento/CatalogGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -492,3 +492,9 @@ type StoreConfig @doc(description: "The type contains information about a store
catalog_default_sort_by : String @doc(description: "Default Sort By.")
root_category_id: Int @doc(description: "The ID of the root category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\RootCategoryId")
}

type SimpleWishlistItem implements WishlistItemInterface @doc(description: "A simple product wish list Item") {
}

type VirtualWishlistItem implements WishlistItemInterface @doc(description: "A virtual product wish list item") {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\ConfigurableProductGraphQl\Model\Wishlist;

use Magento\Catalog\Model\Product;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

/**
* Fetches the simple child sku of configurable product
*/
class ChildSku implements ResolverInterface
{
/**
* @inheritdoc
*/
public function resolve(
Field $field,
$context,
ResolveInfo $info,
array $value = null,
array $args = null
) {
if (!$value['model'] instanceof Product) {
throw new LocalizedException(__('"itemModel" should be a "%instance" instance', [
'instance' => Product::class
]));
}

/** @var Product $product */
$product = $value['model'];
$optionProduct = $product->getCustomOption('simple_product')->getProduct();

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

namespace Magento\ConfigurableProductGraphQl\Model\Wishlist;

use Magento\Catalog\Helper\Product\Configuration;
use Magento\Catalog\Model\Product\Configuration\Item\ItemInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

/**
* Fetches the selected configurable options
*/
class ConfigurableOptions implements ResolverInterface
{
/**
* @var Configuration
*/
private $configurationHelper;

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

/**
* @inheritdoc
*/
public function resolve(
Field $field,
$context,
ResolveInfo $info,
array $value = null,
array $args = null
) {
if (!$value['itemModel'] instanceof ItemInterface) {
throw new LocalizedException(__('"itemModel" should be a "%instance" instance', [
'instance' => ItemInterface::class
]));
}

/** @var ItemInterface $item */
$item = $value['itemModel'];
$result = [];

foreach ($this->configurationHelper->getOptions($item) as $option) {
$result[] = [
'id' => $option['option_id'],
'option_label' => $option['label'],
'value_id' => $option['option_value'],
'value_label' => $option['value'],
];
}

return $result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,11 @@
</argument>
</arguments>
</type>
<type name="Magento\WishlistGraphQl\Model\Resolver\Type\WishlistItemType">
<arguments>
<argument name="supportedTypes" xsi:type="array">
<item name="configurable" xsi:type="string">ConfigurableWishlistItem</item>
</argument>
</arguments>
</type>
</config>
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,8 @@ type SelectedConfigurableOption {
value_id: Int!
value_label: String!
}

type ConfigurableWishlistItem implements WishlistItemInterface @doc(description: "A configurable product wish list item"){
child_sku: String! @doc(description: "The SKU of the simple product corresponding to a set of selected configurable options") @resolver(class: "\\Magento\\ConfigurableProductGraphQl\\Model\\Wishlist\\ChildSku")
configurable_options: [SelectedConfigurableOption!] @resolver(class: "\\Magento\\ConfigurableProductGraphQl\\Model\\Wishlist\\ConfigurableOptions") @doc (description: "An array of selected configurable options")
}
Loading