Skip to content

Commit 7a166c2

Browse files
committed
Merge branch '2.4-develop' of github.com:magento/magento2 into 1724-support-batches-synchronization
2 parents 6a9f506 + d1ff2ca commit 7a166c2

File tree

57 files changed

+1642
-306
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1642
-306
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
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\Bundle\Model\Product;
9+
10+
use Magento\Bundle\Helper\Catalog\Product\Configuration;
11+
use Magento\Bundle\Model\Option;
12+
use Magento\Catalog\Model\Product;
13+
use Magento\Catalog\Model\Product\Configuration\Item\ItemInterface;
14+
use Magento\Framework\Pricing\Helper\Data;
15+
use Magento\Framework\Serialize\SerializerInterface;
16+
17+
/**
18+
* Data provider for bundled product options
19+
*/
20+
class BundleOptionDataProvider
21+
{
22+
/**
23+
* @var Data
24+
*/
25+
private $pricingHelper;
26+
27+
/**
28+
* @var SerializerInterface
29+
*/
30+
private $serializer;
31+
32+
/**
33+
* @var Configuration
34+
*/
35+
private $configuration;
36+
37+
/**
38+
* @param Data $pricingHelper
39+
* @param SerializerInterface $serializer
40+
* @param Configuration $configuration
41+
*/
42+
public function __construct(
43+
Data $pricingHelper,
44+
SerializerInterface $serializer,
45+
Configuration $configuration
46+
) {
47+
$this->pricingHelper = $pricingHelper;
48+
$this->serializer = $serializer;
49+
$this->configuration = $configuration;
50+
}
51+
52+
/**
53+
* Extract data for a bundled item
54+
*
55+
* @param ItemInterface $item
56+
*
57+
* @return array
58+
*/
59+
public function getData(ItemInterface $item): array
60+
{
61+
$options = [];
62+
$product = $item->getProduct();
63+
$optionsQuoteItemOption = $item->getOptionByCode('bundle_option_ids');
64+
$bundleOptionsIds = $optionsQuoteItemOption
65+
? $this->serializer->unserialize($optionsQuoteItemOption->getValue())
66+
: [];
67+
68+
/** @var Type $typeInstance */
69+
$typeInstance = $product->getTypeInstance();
70+
71+
if ($bundleOptionsIds) {
72+
$selectionsQuoteItemOption = $item->getOptionByCode('bundle_selection_ids');
73+
$optionsCollection = $typeInstance->getOptionsByIds($bundleOptionsIds, $product);
74+
$bundleSelectionIds = $this->serializer->unserialize($selectionsQuoteItemOption->getValue());
75+
76+
if (!empty($bundleSelectionIds)) {
77+
$selectionsCollection = $typeInstance->getSelectionsByIds($bundleSelectionIds, $product);
78+
$bundleOptions = $optionsCollection->appendSelections($selectionsCollection, true);
79+
80+
$options = $this->buildBundleOptions($bundleOptions, $item);
81+
}
82+
}
83+
84+
return $options;
85+
}
86+
87+
/**
88+
* Build bundle product options based on current selection
89+
*
90+
* @param Option[] $bundleOptions
91+
* @param ItemInterface $item
92+
*
93+
* @return array
94+
*/
95+
private function buildBundleOptions(array $bundleOptions, ItemInterface $item): array
96+
{
97+
$options = [];
98+
foreach ($bundleOptions as $bundleOption) {
99+
if (!$bundleOption->getSelections()) {
100+
continue;
101+
}
102+
103+
$options[] = [
104+
'id' => $bundleOption->getId(),
105+
'label' => $bundleOption->getTitle(),
106+
'type' => $bundleOption->getType(),
107+
'values' => $this->buildBundleOptionValues($bundleOption->getSelections(), $item),
108+
];
109+
}
110+
111+
return $options;
112+
}
113+
114+
/**
115+
* Build bundle product option values based on current selection
116+
*
117+
* @param Product[] $selections
118+
* @param ItemInterface $item
119+
*
120+
* @return array
121+
*/
122+
private function buildBundleOptionValues(array $selections, ItemInterface $item): array
123+
{
124+
$product = $item->getProduct();
125+
$values = [];
126+
127+
foreach ($selections as $selection) {
128+
$qty = (float) $this->configuration->getSelectionQty($product, $selection->getSelectionId());
129+
if (!$qty) {
130+
continue;
131+
}
132+
133+
$selectionPrice = $this->configuration->getSelectionFinalPrice($item, $selection);
134+
$values[] = [
135+
'label' => $selection->getName(),
136+
'id' => $selection->getSelectionId(),
137+
'quantity' => $qty,
138+
'price' => $this->pricingHelper->currency($selectionPrice, false, false),
139+
];
140+
}
141+
142+
return $values;
143+
}
144+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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\BundleGraphQl\Model\Wishlist;
9+
10+
use Magento\Bundle\Model\Product\BundleOptionDataProvider;
11+
use Magento\Catalog\Model\Product\Configuration\Item\ItemInterface;
12+
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\Framework\GraphQl\Config\Element\Field;
14+
use Magento\Framework\GraphQl\Query\ResolverInterface;
15+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
16+
17+
/**
18+
* Fetches the selected bundle options
19+
*/
20+
class BundleOptions implements ResolverInterface
21+
{
22+
/**
23+
* @var BundleOptionDataProvider
24+
*/
25+
private $bundleOptionDataProvider;
26+
27+
/**
28+
* @param BundleOptionDataProvider $bundleOptionDataProvider
29+
*/
30+
public function __construct(
31+
BundleOptionDataProvider $bundleOptionDataProvider
32+
) {
33+
$this->bundleOptionDataProvider = $bundleOptionDataProvider;
34+
}
35+
36+
/**
37+
* @inheritdoc
38+
*/
39+
public function resolve(
40+
Field $field,
41+
$context,
42+
ResolveInfo $info,
43+
array $value = null,
44+
array $args = null
45+
) {
46+
if (!$value['itemModel'] instanceof ItemInterface) {
47+
throw new LocalizedException(__('"itemModel" should be a "%instance" instance', [
48+
'instance' => ItemInterface::class
49+
]));
50+
}
51+
52+
return $this->bundleOptionDataProvider->getData($value['itemModel']);
53+
}
54+
}

app/code/Magento/BundleGraphQl/etc/graphql/di.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,11 @@
100100
</argument>
101101
</arguments>
102102
</type>
103+
<type name="Magento\WishlistGraphQl\Model\Resolver\Type\WishlistItemType">
104+
<arguments>
105+
<argument name="supportedTypes" xsi:type="array">
106+
<item name="bundle" xsi:type="string">BundleWishlistItem</item>
107+
</argument>
108+
</arguments>
109+
</type>
103110
</config>

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,7 @@ type ItemSelectedBundleOptionValue @doc(description: "A list of values for the s
117117
quantity: Float! @doc(description: "Indicates how many of this bundle product were ordered")
118118
price: Money! @doc(description: "The price of the child bundle product")
119119
}
120+
121+
type BundleWishlistItem implements WishlistItemInterface {
122+
bundle_options: [SelectedBundleOption!] @doc(description: "An array containing information about the selected bundle items") @resolver(class: "\\Magento\\BundleGraphQl\\Model\\Wishlist\\BundleOptions")
123+
}

app/code/Magento/CatalogGraphQl/etc/graphql/di.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,12 @@
180180
<argument name="templateFilterModel" xsi:type="string">Magento\Widget\Model\Template\FilterEmulate</argument>
181181
</arguments>
182182
</type>
183+
<type name="Magento\WishlistGraphQl\Model\Resolver\Type\WishlistItemType">
184+
<arguments>
185+
<argument name="supportedTypes" xsi:type="array">
186+
<item name="simple" xsi:type="string">SimpleWishlistItem</item>
187+
<item name="virtual" xsi:type="string">VirtualWishlistItem</item>
188+
</argument>
189+
</arguments>
190+
</type>
183191
</config>

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,3 +492,9 @@ type StoreConfig @doc(description: "The type contains information about a store
492492
catalog_default_sort_by : String @doc(description: "Default Sort By.")
493493
root_category_id: Int @doc(description: "The ID of the root category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\RootCategoryId")
494494
}
495+
496+
type SimpleWishlistItem implements WishlistItemInterface @doc(description: "A simple product wish list Item") {
497+
}
498+
499+
type VirtualWishlistItem implements WishlistItemInterface @doc(description: "A virtual product wish list item") {
500+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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\ConfigurableProductGraphQl\Model\Wishlist;
9+
10+
use Magento\Catalog\Model\Product;
11+
use Magento\Framework\Exception\LocalizedException;
12+
use Magento\Framework\GraphQl\Config\Element\Field;
13+
use Magento\Framework\GraphQl\Query\ResolverInterface;
14+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
15+
16+
/**
17+
* Fetches the simple child sku of configurable product
18+
*/
19+
class ChildSku implements ResolverInterface
20+
{
21+
/**
22+
* @inheritdoc
23+
*/
24+
public function resolve(
25+
Field $field,
26+
$context,
27+
ResolveInfo $info,
28+
array $value = null,
29+
array $args = null
30+
) {
31+
if (!$value['model'] instanceof Product) {
32+
throw new LocalizedException(__('"itemModel" should be a "%instance" instance', [
33+
'instance' => Product::class
34+
]));
35+
}
36+
37+
/** @var Product $product */
38+
$product = $value['model'];
39+
$optionProduct = $product->getCustomOption('simple_product')->getProduct();
40+
41+
return $optionProduct->getSku();
42+
}
43+
}
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\ConfigurableProductGraphQl\Model\Wishlist;
9+
10+
use Magento\Catalog\Helper\Product\Configuration;
11+
use Magento\Catalog\Model\Product\Configuration\Item\ItemInterface;
12+
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\Framework\GraphQl\Config\Element\Field;
14+
use Magento\Framework\GraphQl\Query\ResolverInterface;
15+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
16+
17+
/**
18+
* Fetches the selected configurable options
19+
*/
20+
class ConfigurableOptions implements ResolverInterface
21+
{
22+
/**
23+
* @var Configuration
24+
*/
25+
private $configurationHelper;
26+
27+
/**
28+
* @param Configuration $configurationHelper
29+
*/
30+
public function __construct(
31+
Configuration $configurationHelper
32+
) {
33+
$this->configurationHelper = $configurationHelper;
34+
}
35+
36+
/**
37+
* @inheritdoc
38+
*/
39+
public function resolve(
40+
Field $field,
41+
$context,
42+
ResolveInfo $info,
43+
array $value = null,
44+
array $args = null
45+
) {
46+
if (!$value['itemModel'] instanceof ItemInterface) {
47+
throw new LocalizedException(__('"itemModel" should be a "%instance" instance', [
48+
'instance' => ItemInterface::class
49+
]));
50+
}
51+
52+
/** @var ItemInterface $item */
53+
$item = $value['itemModel'];
54+
$result = [];
55+
56+
foreach ($this->configurationHelper->getOptions($item) as $option) {
57+
$result[] = [
58+
'id' => $option['option_id'],
59+
'option_label' => $option['label'],
60+
'value_id' => $option['option_value'],
61+
'value_label' => $option['value'],
62+
];
63+
}
64+
65+
return $result;
66+
}
67+
}

app/code/Magento/ConfigurableProductGraphQl/etc/graphql/di.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,11 @@
3636
</argument>
3737
</arguments>
3838
</type>
39+
<type name="Magento\WishlistGraphQl\Model\Resolver\Type\WishlistItemType">
40+
<arguments>
41+
<argument name="supportedTypes" xsi:type="array">
42+
<item name="configurable" xsi:type="string">ConfigurableWishlistItem</item>
43+
</argument>
44+
</arguments>
45+
</type>
3946
</config>

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,8 @@ type SelectedConfigurableOption {
6868
value_id: Int!
6969
value_label: String!
7070
}
71+
72+
type ConfigurableWishlistItem implements WishlistItemInterface @doc(description: "A configurable product wish list item"){
73+
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")
74+
configurable_options: [SelectedConfigurableOption!] @resolver(class: "\\Magento\\ConfigurableProductGraphQl\\Model\\Wishlist\\ConfigurableOptions") @doc (description: "An array of selected configurable options")
75+
}

0 commit comments

Comments
 (0)