Skip to content

Commit

Permalink
Merge pull request #7530 from magento-gl/Hammer_Graphql_Community_Bac…
Browse files Browse the repository at this point in the history
…klog_22032022

Hammer graphql community backlog 22032022
  • Loading branch information
sidolov committed Apr 5, 2022
2 parents 5c3867e + 594d478 commit 5c97ea7
Show file tree
Hide file tree
Showing 42 changed files with 1,629 additions and 295 deletions.
81 changes: 81 additions & 0 deletions app/code/Magento/BundleGraphQl/Model/Resolver/PriceRange.php
@@ -0,0 +1,81 @@
<?php

/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\BundleGraphQl\Model\Resolver;

use Magento\CatalogGraphQl\Model\PriceRangeDataProvider;
use Magento\CatalogGraphQl\Model\Resolver\Product\Price\Discount;
use Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool as PriceProviderPool;
use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Deferred\Product as ProductDataProvider;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

/**
* Format product's pricing information for price_range field
*/
class PriceRange implements ResolverInterface
{
/**
* @var Discount
*/
private Discount $discount;

/**
* @var PriceProviderPool
*/
private PriceProviderPool $priceProviderPool;

/**
* @var ProductDataProvider
*/
private ProductDataProvider $productDataProvider;

/**
* @var PriceRangeDataProvider
*/
private PriceRangeDataProvider $priceRangeDataProvider;

/**
* @param PriceProviderPool $priceProviderPool
* @param Discount $discount
* @param ProductDataProvider|null $productDataProvider
* @param PriceRangeDataProvider|null $priceRangeDataProvider
*/
public function __construct(
PriceProviderPool $priceProviderPool,
Discount $discount,
ProductDataProvider $productDataProvider = null,
PriceRangeDataProvider $priceRangeDataProvider = null
) {
$this->priceProviderPool = $priceProviderPool;
$this->discount = $discount;
$this->productDataProvider = $productDataProvider
?? ObjectManager::getInstance()->get(ProductDataProvider::class);
$this->priceRangeDataProvider = $priceRangeDataProvider
?? ObjectManager::getInstance()->get(PriceRangeDataProvider::class);
}

/**
* @inheritDoc
*/
public function resolve(
Field $field,
$context,
ResolveInfo $info,
array $value = null,
array $args = null
) {
$this->productDataProvider->addProductSku($value['sku']);
$productData = $this->productDataProvider->getProductBySku($value['sku']);
$value['model'] = $productData['model'];

return $this->priceRangeDataProvider->prepare($context, $info, $value);
}
}
1 change: 1 addition & 0 deletions app/code/Magento/BundleGraphQl/etc/schema.graphqls
Expand Up @@ -55,6 +55,7 @@ type BundleItem @doc(description: "Defines an individual item within a bundle pr
type: String @doc(description: "The input type that the customer uses to select the item. Examples include radio button and checkbox.")
position: Int @doc(description: "A number indicating the sequence order of this item compared to the other bundle items.")
sku: String @doc(description: "The SKU of the bundle product.")
price_range: PriceRange! @doc(description: "The range of prices for the product") @resolver(class: "Magento\\BundleGraphQl\\Model\\Resolver\\PriceRange")
options: [BundleItemOption] @doc(description: "An array of additional options for this bundle item.") @resolver(class: "Magento\\BundleGraphQl\\Model\\Resolver\\BundleItemLinks")
}

Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Expand Up @@ -8,16 +8,15 @@
namespace Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\Builder;

use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
use Magento\CatalogGraphQl\DataProvider\CategoryAttributesMapper;
use Magento\CatalogGraphQl\DataProvider\Category\Query\CategoryAttributeQuery;
use Magento\CatalogGraphQl\DataProvider\CategoryAttributesMapper;
use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\Formatter\LayerFormatter;
use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\LayerBuilderInterface;
use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\RootCategoryProvider;
use Magento\Framework\Api\Search\AggregationInterface;
use Magento\Framework\Api\Search\AggregationValueInterface;
use Magento\Framework\Api\Search\BucketInterface;
use Magento\Framework\App\ResourceConnection;
use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\Formatter\LayerFormatter;
use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\Builder\Aggregations;

/**
* Category layer builder
Expand All @@ -36,45 +35,45 @@ class Category implements LayerBuilderInterface
*/
private static $bucketMap = [
self::CATEGORY_BUCKET => [
'request_name' => 'category_id',
'request_name' => 'category_uid',
'label' => 'Category'
],
];

/**
* @var CategoryAttributeQuery
*/
private $categoryAttributeQuery;
private CategoryAttributeQuery $categoryAttributeQuery;

/**
* @var CategoryAttributesMapper
*/
private $attributesMapper;
private CategoryAttributesMapper $attributesMapper;

/**
* @var ResourceConnection
*/
private $resourceConnection;
private ResourceConnection $resourceConnection;

/**
* @var RootCategoryProvider
*/
private $rootCategoryProvider;
private RootCategoryProvider $rootCategoryProvider;

/**
* @var LayerFormatter
*/
private $layerFormatter;
private LayerFormatter $layerFormatter;

/**
* @var CollectionFactory
*/
private $categoryCollectionFactory;
private CollectionFactory $categoryCollectionFactory;

/**
* @var Aggregations\Category\IncludeDirectChildrenOnly
*/
private $includeDirectChildrenOnly;
private Aggregations\Category\IncludeDirectChildrenOnly $includeDirectChildrenOnly;

/**
* @param CategoryAttributeQuery $categoryAttributeQuery
Expand Down Expand Up @@ -152,7 +151,7 @@ function (AggregationValueInterface $value) {
foreach ($bucket->getValues() as $value) {
$categoryId = $value->getValue();
if (!\in_array($categoryId, $categoryIds, true)) {
continue ;
continue;
}
$result['options'][] = $this->layerFormatter->buildItem(
$categoryLabels[$categoryId] ?? $categoryId,
Expand Down
185 changes: 185 additions & 0 deletions app/code/Magento/CatalogGraphQl/Model/PriceRangeDataProvider.php
@@ -0,0 +1,185 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CatalogGraphQl\Model;

use Exception;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Model\Product;
use Magento\CatalogGraphQl\Model\Resolver\Product\Price\Discount;
use Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool as PriceProviderPool;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Query\Resolver\Value;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\Pricing\SaleableInterface;
use Magento\GraphQl\Model\Query\ContextInterface;
use Magento\Store\Api\Data\StoreInterface;

/**
* Prepares search query based on search text.
*/
class PriceRangeDataProvider
{
private const STORE_FILTER_CACHE_KEY = '_cache_instance_store_filter';

/**
* @var Discount
*/
private Discount $discount;

/**
* @var PriceProviderPool
*/
private PriceProviderPool $priceProviderPool;

/**
* @param PriceProviderPool $priceProviderPool
* @param Discount $discount
*/
public function __construct(
PriceProviderPool $priceProviderPool,
Discount $discount
) {
$this->priceProviderPool = $priceProviderPool;
$this->discount = $discount;
}

/**
* Prepare Query object based on search text
*
* @param ContextInterface $context
* @param ResolveInfo $info
* @param array $value
* @throws Exception
* @return mixed|Value
*/
public function prepare(ContextInterface $context, ResolveInfo $info, array $value): array
{
if (!isset($value['model'])) {
throw new LocalizedException(__('"model" value should be specified'));
}
/** @var StoreInterface $store */
$store = $context->getExtensionAttributes()->getStore();

/** @var Product $product */
$product = $value['model'];
$product->unsetData('minimal_price');
// add store filter for the product
$product->setData(self::STORE_FILTER_CACHE_KEY, $store);

if ($context) {
$customerGroupId = $context->getExtensionAttributes()->getCustomerGroupId();
if ($customerGroupId !== null) {
$product->setCustomerGroupId($customerGroupId);
}
}

$requestedFields = $info->getFieldSelection(10);
$returnArray = [];

$returnArray['minimum_price'] = ($requestedFields['minimum_price'] ?? 0) ? ($this->canShowPrice($product) ?
$this->getMinimumProductPrice($product, $store) : $this->formatEmptyResult()) : $this->formatEmptyResult();
$returnArray['maximum_price'] = ($requestedFields['maximum_price'] ?? 0) ? ($this->canShowPrice($product) ?
$this->getMaximumProductPrice($product, $store) : $this->formatEmptyResult()) : $this->formatEmptyResult();

return $returnArray;
}

/**
* Get formatted minimum product price
*
* @param SaleableInterface $product
* @param StoreInterface $store
* @return array
*/
private function getMinimumProductPrice(SaleableInterface $product, StoreInterface $store): array
{
$priceProvider = $this->priceProviderPool->getProviderByProductType($product->getTypeId());
$minPriceArray = $this->formatPrice(
(float)$priceProvider->getMinimalRegularPrice($product)->getValue(),
(float)$priceProvider->getMinimalFinalPrice($product)->getValue(),
$store
);
$minPriceArray['model'] = $product;

return $minPriceArray;
}

/**
* Get formatted maximum product price
*
* @param SaleableInterface $product
* @param StoreInterface $store
* @return array
*/
private function getMaximumProductPrice(SaleableInterface $product, StoreInterface $store): array
{
$priceProvider = $this->priceProviderPool->getProviderByProductType($product->getTypeId());
$maxPriceArray = $this->formatPrice(
(float)$priceProvider->getMaximalRegularPrice($product)->getValue(),
(float)$priceProvider->getMaximalFinalPrice($product)->getValue(),
$store
);
$maxPriceArray['model'] = $product;

return $maxPriceArray;
}

/**
* Format price for GraphQl output
*
* @param float $regularPrice
* @param float $finalPrice
* @param StoreInterface $store
* @return array
*/
private function formatPrice(float $regularPrice, float $finalPrice, StoreInterface $store): array
{
return [
'regular_price' => [
'value' => $regularPrice,
'currency' => $store->getCurrentCurrencyCode(),
],
'final_price' => [
'value' => $finalPrice,
'currency' => $store->getCurrentCurrencyCode(),
],
'discount' => $this->discount->getDiscountByDifference($regularPrice, $finalPrice),
];
}

/**
* Check if the product is allowed to show price
*
* @param ProductInterface $product
* @return bool
*/
private function canShowPrice(ProductInterface $product): bool
{
return $product->hasData('can_show_price') ? $product->getData('can_show_price') : true;
}

/**
* Format empty result
*
* @return array
*/
private function formatEmptyResult(): array
{
return [
'regular_price' => [
'value' => null,
'currency' => null,
],
'final_price' => [
'value' => null,
'currency' => null,
],
'discount' => null,
];
}
}

0 comments on commit 5c97ea7

Please sign in to comment.