Skip to content

Commit 5c97ea7

Browse files
authored
Merge pull request #7530 from magento-gl/Hammer_Graphql_Community_Backlog_22032022
Hammer graphql community backlog 22032022
2 parents 5c3867e + 594d478 commit 5c97ea7

File tree

42 files changed

+1629
-295
lines changed

Some content is hidden

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

42 files changed

+1629
-295
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Magento\BundleGraphQl\Model\Resolver;
10+
11+
use Magento\CatalogGraphQl\Model\PriceRangeDataProvider;
12+
use Magento\CatalogGraphQl\Model\Resolver\Product\Price\Discount;
13+
use Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool as PriceProviderPool;
14+
use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Deferred\Product as ProductDataProvider;
15+
use Magento\Framework\App\ObjectManager;
16+
use Magento\Framework\GraphQl\Config\Element\Field;
17+
use Magento\Framework\GraphQl\Query\ResolverInterface;
18+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
19+
20+
/**
21+
* Format product's pricing information for price_range field
22+
*/
23+
class PriceRange implements ResolverInterface
24+
{
25+
/**
26+
* @var Discount
27+
*/
28+
private Discount $discount;
29+
30+
/**
31+
* @var PriceProviderPool
32+
*/
33+
private PriceProviderPool $priceProviderPool;
34+
35+
/**
36+
* @var ProductDataProvider
37+
*/
38+
private ProductDataProvider $productDataProvider;
39+
40+
/**
41+
* @var PriceRangeDataProvider
42+
*/
43+
private PriceRangeDataProvider $priceRangeDataProvider;
44+
45+
/**
46+
* @param PriceProviderPool $priceProviderPool
47+
* @param Discount $discount
48+
* @param ProductDataProvider|null $productDataProvider
49+
* @param PriceRangeDataProvider|null $priceRangeDataProvider
50+
*/
51+
public function __construct(
52+
PriceProviderPool $priceProviderPool,
53+
Discount $discount,
54+
ProductDataProvider $productDataProvider = null,
55+
PriceRangeDataProvider $priceRangeDataProvider = null
56+
) {
57+
$this->priceProviderPool = $priceProviderPool;
58+
$this->discount = $discount;
59+
$this->productDataProvider = $productDataProvider
60+
?? ObjectManager::getInstance()->get(ProductDataProvider::class);
61+
$this->priceRangeDataProvider = $priceRangeDataProvider
62+
?? ObjectManager::getInstance()->get(PriceRangeDataProvider::class);
63+
}
64+
65+
/**
66+
* @inheritDoc
67+
*/
68+
public function resolve(
69+
Field $field,
70+
$context,
71+
ResolveInfo $info,
72+
array $value = null,
73+
array $args = null
74+
) {
75+
$this->productDataProvider->addProductSku($value['sku']);
76+
$productData = $this->productDataProvider->getProductBySku($value['sku']);
77+
$value['model'] = $productData['model'];
78+
79+
return $this->priceRangeDataProvider->prepare($context, $info, $value);
80+
}
81+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ type BundleItem @doc(description: "Defines an individual item within a bundle pr
5555
type: String @doc(description: "The input type that the customer uses to select the item. Examples include radio button and checkbox.")
5656
position: Int @doc(description: "A number indicating the sequence order of this item compared to the other bundle items.")
5757
sku: String @doc(description: "The SKU of the bundle product.")
58+
price_range: PriceRange! @doc(description: "The range of prices for the product") @resolver(class: "Magento\\BundleGraphQl\\Model\\Resolver\\PriceRange")
5859
options: [BundleItemOption] @doc(description: "An array of additional options for this bundle item.") @resolver(class: "Magento\\BundleGraphQl\\Model\\Resolver\\BundleItemLinks")
5960
}
6061

Loading

app/code/Magento/CatalogGraphQl/DataProvider/Product/LayeredNavigation/Builder/Category.php

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,15 @@
88
namespace Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\Builder;
99

1010
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
11-
use Magento\CatalogGraphQl\DataProvider\CategoryAttributesMapper;
1211
use Magento\CatalogGraphQl\DataProvider\Category\Query\CategoryAttributeQuery;
12+
use Magento\CatalogGraphQl\DataProvider\CategoryAttributesMapper;
13+
use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\Formatter\LayerFormatter;
1314
use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\LayerBuilderInterface;
1415
use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\RootCategoryProvider;
1516
use Magento\Framework\Api\Search\AggregationInterface;
1617
use Magento\Framework\Api\Search\AggregationValueInterface;
1718
use Magento\Framework\Api\Search\BucketInterface;
1819
use Magento\Framework\App\ResourceConnection;
19-
use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\Formatter\LayerFormatter;
20-
use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\Builder\Aggregations;
2120

2221
/**
2322
* Category layer builder
@@ -36,45 +35,45 @@ class Category implements LayerBuilderInterface
3635
*/
3736
private static $bucketMap = [
3837
self::CATEGORY_BUCKET => [
39-
'request_name' => 'category_id',
38+
'request_name' => 'category_uid',
4039
'label' => 'Category'
4140
],
4241
];
4342

4443
/**
4544
* @var CategoryAttributeQuery
4645
*/
47-
private $categoryAttributeQuery;
46+
private CategoryAttributeQuery $categoryAttributeQuery;
4847

4948
/**
5049
* @var CategoryAttributesMapper
5150
*/
52-
private $attributesMapper;
51+
private CategoryAttributesMapper $attributesMapper;
5352

5453
/**
5554
* @var ResourceConnection
5655
*/
57-
private $resourceConnection;
56+
private ResourceConnection $resourceConnection;
5857

5958
/**
6059
* @var RootCategoryProvider
6160
*/
62-
private $rootCategoryProvider;
61+
private RootCategoryProvider $rootCategoryProvider;
6362

6463
/**
6564
* @var LayerFormatter
6665
*/
67-
private $layerFormatter;
66+
private LayerFormatter $layerFormatter;
6867

6968
/**
7069
* @var CollectionFactory
7170
*/
72-
private $categoryCollectionFactory;
71+
private CollectionFactory $categoryCollectionFactory;
7372

7473
/**
7574
* @var Aggregations\Category\IncludeDirectChildrenOnly
7675
*/
77-
private $includeDirectChildrenOnly;
76+
private Aggregations\Category\IncludeDirectChildrenOnly $includeDirectChildrenOnly;
7877

7978
/**
8079
* @param CategoryAttributeQuery $categoryAttributeQuery
@@ -152,7 +151,7 @@ function (AggregationValueInterface $value) {
152151
foreach ($bucket->getValues() as $value) {
153152
$categoryId = $value->getValue();
154153
if (!\in_array($categoryId, $categoryIds, true)) {
155-
continue ;
154+
continue;
156155
}
157156
$result['options'][] = $this->layerFormatter->buildItem(
158157
$categoryLabels[$categoryId] ?? $categoryId,
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
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\CatalogGraphQl\Model;
9+
10+
use Exception;
11+
use Magento\Catalog\Api\Data\ProductInterface;
12+
use Magento\Catalog\Model\Product;
13+
use Magento\CatalogGraphQl\Model\Resolver\Product\Price\Discount;
14+
use Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool as PriceProviderPool;
15+
use Magento\Framework\Exception\LocalizedException;
16+
use Magento\Framework\GraphQl\Query\Resolver\Value;
17+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
18+
use Magento\Framework\Pricing\SaleableInterface;
19+
use Magento\GraphQl\Model\Query\ContextInterface;
20+
use Magento\Store\Api\Data\StoreInterface;
21+
22+
/**
23+
* Prepares search query based on search text.
24+
*/
25+
class PriceRangeDataProvider
26+
{
27+
private const STORE_FILTER_CACHE_KEY = '_cache_instance_store_filter';
28+
29+
/**
30+
* @var Discount
31+
*/
32+
private Discount $discount;
33+
34+
/**
35+
* @var PriceProviderPool
36+
*/
37+
private PriceProviderPool $priceProviderPool;
38+
39+
/**
40+
* @param PriceProviderPool $priceProviderPool
41+
* @param Discount $discount
42+
*/
43+
public function __construct(
44+
PriceProviderPool $priceProviderPool,
45+
Discount $discount
46+
) {
47+
$this->priceProviderPool = $priceProviderPool;
48+
$this->discount = $discount;
49+
}
50+
51+
/**
52+
* Prepare Query object based on search text
53+
*
54+
* @param ContextInterface $context
55+
* @param ResolveInfo $info
56+
* @param array $value
57+
* @throws Exception
58+
* @return mixed|Value
59+
*/
60+
public function prepare(ContextInterface $context, ResolveInfo $info, array $value): array
61+
{
62+
if (!isset($value['model'])) {
63+
throw new LocalizedException(__('"model" value should be specified'));
64+
}
65+
/** @var StoreInterface $store */
66+
$store = $context->getExtensionAttributes()->getStore();
67+
68+
/** @var Product $product */
69+
$product = $value['model'];
70+
$product->unsetData('minimal_price');
71+
// add store filter for the product
72+
$product->setData(self::STORE_FILTER_CACHE_KEY, $store);
73+
74+
if ($context) {
75+
$customerGroupId = $context->getExtensionAttributes()->getCustomerGroupId();
76+
if ($customerGroupId !== null) {
77+
$product->setCustomerGroupId($customerGroupId);
78+
}
79+
}
80+
81+
$requestedFields = $info->getFieldSelection(10);
82+
$returnArray = [];
83+
84+
$returnArray['minimum_price'] = ($requestedFields['minimum_price'] ?? 0) ? ($this->canShowPrice($product) ?
85+
$this->getMinimumProductPrice($product, $store) : $this->formatEmptyResult()) : $this->formatEmptyResult();
86+
$returnArray['maximum_price'] = ($requestedFields['maximum_price'] ?? 0) ? ($this->canShowPrice($product) ?
87+
$this->getMaximumProductPrice($product, $store) : $this->formatEmptyResult()) : $this->formatEmptyResult();
88+
89+
return $returnArray;
90+
}
91+
92+
/**
93+
* Get formatted minimum product price
94+
*
95+
* @param SaleableInterface $product
96+
* @param StoreInterface $store
97+
* @return array
98+
*/
99+
private function getMinimumProductPrice(SaleableInterface $product, StoreInterface $store): array
100+
{
101+
$priceProvider = $this->priceProviderPool->getProviderByProductType($product->getTypeId());
102+
$minPriceArray = $this->formatPrice(
103+
(float)$priceProvider->getMinimalRegularPrice($product)->getValue(),
104+
(float)$priceProvider->getMinimalFinalPrice($product)->getValue(),
105+
$store
106+
);
107+
$minPriceArray['model'] = $product;
108+
109+
return $minPriceArray;
110+
}
111+
112+
/**
113+
* Get formatted maximum product price
114+
*
115+
* @param SaleableInterface $product
116+
* @param StoreInterface $store
117+
* @return array
118+
*/
119+
private function getMaximumProductPrice(SaleableInterface $product, StoreInterface $store): array
120+
{
121+
$priceProvider = $this->priceProviderPool->getProviderByProductType($product->getTypeId());
122+
$maxPriceArray = $this->formatPrice(
123+
(float)$priceProvider->getMaximalRegularPrice($product)->getValue(),
124+
(float)$priceProvider->getMaximalFinalPrice($product)->getValue(),
125+
$store
126+
);
127+
$maxPriceArray['model'] = $product;
128+
129+
return $maxPriceArray;
130+
}
131+
132+
/**
133+
* Format price for GraphQl output
134+
*
135+
* @param float $regularPrice
136+
* @param float $finalPrice
137+
* @param StoreInterface $store
138+
* @return array
139+
*/
140+
private function formatPrice(float $regularPrice, float $finalPrice, StoreInterface $store): array
141+
{
142+
return [
143+
'regular_price' => [
144+
'value' => $regularPrice,
145+
'currency' => $store->getCurrentCurrencyCode(),
146+
],
147+
'final_price' => [
148+
'value' => $finalPrice,
149+
'currency' => $store->getCurrentCurrencyCode(),
150+
],
151+
'discount' => $this->discount->getDiscountByDifference($regularPrice, $finalPrice),
152+
];
153+
}
154+
155+
/**
156+
* Check if the product is allowed to show price
157+
*
158+
* @param ProductInterface $product
159+
* @return bool
160+
*/
161+
private function canShowPrice(ProductInterface $product): bool
162+
{
163+
return $product->hasData('can_show_price') ? $product->getData('can_show_price') : true;
164+
}
165+
166+
/**
167+
* Format empty result
168+
*
169+
* @return array
170+
*/
171+
private function formatEmptyResult(): array
172+
{
173+
return [
174+
'regular_price' => [
175+
'value' => null,
176+
'currency' => null,
177+
],
178+
'final_price' => [
179+
'value' => null,
180+
'currency' => null,
181+
],
182+
'discount' => null,
183+
];
184+
}
185+
}

0 commit comments

Comments
 (0)