Skip to content
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

Add new GraphQL query for single product retrieval #28316

Open
wants to merge 7 commits into
base: 2.4-develop
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CatalogGraphQl\Model\Resolver\Product\DataProvider;

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ProductFactory;
use Magento\Catalog\Model\ResourceModel\Product as ProductResourceModel;

/**
* Product data provider, used for GraphQL resolver processing.
*/
class ProductDataProvider implements ProductDataProviderInterface
{
/**
* @var ProductResourceModel
*/
private $productResourceModel;

/**
* @var ProductFactory
*/
private $productFactory;

/**
* ProductDataProvider constructor.
*
* @param ProductResourceModel $productResourceModel
* @param ProductFactory $productFactory
*/
public function __construct(
ProductResourceModel $productResourceModel,
ProductFactory $productFactory
) {
$this->productResourceModel = $productResourceModel;
$this->productFactory = $productFactory;
}

/**
* Get list of products by IDs with full data set
*
* @param array $productIds
* @param array $attributeCodes
* @return ProductInterface[]|Product[]
*/
public function getProductByIds(array $productIds, array $attributeCodes): array
{
$products = [];

foreach ($productIds as $productId) {
/** @var Product $product */
$product = $this->productFactory->create();
$this->productResourceModel->load($product, $productId, $attributeCodes);
$products[] = $product;
}

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

namespace Magento\CatalogGraphQl\Model\Resolver\Product\DataProvider;

use Magento\Catalog\Api\Data\ProductInterface;

/**
* Provides product data by product IDs.
*/
interface ProductDataProviderInterface
{
/**
* Retrieve product by product IDs.
*
* @param array $productIds
* @param array $attributeCodes
* @return ProductInterface[]
*/
public function getProductByIds(array $productIds, array $attributeCodes): array;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CatalogGraphQl\Model\Resolver\Product;

use Magento\Catalog\Model\Product;
use Magento\Framework\GraphQl\Query\Resolver\IdentityInterface;

/**
* Identity for resolved products by IDs
*/
class ProductsByIdIdentity implements IdentityInterface
{
/**
* @var string
*/
private $cacheTag = Product::CACHE_TAG;

/**
* Get product ids for cache tag
*
* @param array $resolvedData
* @return array
*/
public function getIdentities(array $resolvedData): array
{
return empty($resolvedData['ids']) ?
[] : [$this->cacheTag, implode('_', $resolvedData['ids'])];
}
}
70 changes: 70 additions & 0 deletions app/code/Magento/CatalogGraphQl/Model/Resolver/ProductsByID.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CatalogGraphQl\Model\Resolver;

use Magento\CatalogGraphQl\Model\Resolver\Product\DataProvider\ProductDataProviderInterface;
use Magento\CatalogGraphQl\Model\Resolver\Product\ProductFieldsSelector;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

/**
* Products by ID resolver, used for GraphQL request processing.
*/
class ProductsByID implements ResolverInterface
{
/**
* @var ProductDataProviderInterface
*/
private $productDataProvider;

/**
* @var ProductFieldsSelector
*/
private $productFieldsSelector;

/**
* ProductsByID constructor.
*
* @param ProductDataProviderInterface $productDataProvider
* @param ProductFieldsSelector $productFieldsSelector
*/
public function __construct(
ProductDataProviderInterface $productDataProvider,
ProductFieldsSelector $productFieldsSelector
) {
$this->productDataProvider = $productDataProvider;
$this->productFieldsSelector = $productFieldsSelector;
}

/**
* @inheritdoc
*/
public function resolve(
Field $field,
$context,
ResolveInfo $info,
array $value = null,
array $args = null
) {
$productIds = ($args['ids'] ?? []);
$fields = $this->productFieldsSelector->getProductFieldsFromInfo($info);

/** @var \Magento\Catalog\Model\Product[] $products */
$products = $this->productDataProvider->getProductByIds($productIds, $fields);
$data = [];

foreach ($products as $product) {
$productData = $product->getData();
$productData['model'] = $product;
$data[] = $productData;
}

return $data;
}
}
1 change: 1 addition & 0 deletions app/code/Magento/CatalogGraphQl/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,5 @@
<preference type="\Magento\CatalogGraphQl\Model\Resolver\Product\Price\Provider" for="\Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderInterface"/>

<preference type="Magento\CatalogGraphQl\Model\Resolver\Products\Query\Search" for="Magento\CatalogGraphQl\Model\Resolver\Products\Query\ProductQueryInterface"/>
<preference type="Magento\CatalogGraphQl\Model\Resolver\Product\DataProvider\ProductDataProvider" for="Magento\CatalogGraphQl\Model\Resolver\Product\DataProvider\ProductDataProviderInterface"/>
</config>
4 changes: 4 additions & 0 deletions app/code/Magento/CatalogGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ type Query {
sort: ProductAttributeSortInput @doc(description: "Specifies which attributes to sort on, and whether to return the results in ascending or descending order.")
): Products
@resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes.") @cache(cacheIdentity: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Identity")
productsByID (
ids: [ID!]! @doc(description: "Product IDs.")
): [ProductInterface]
@resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\ProductsByID") @doc(description: "The productsByID query fetches products that match the specified IDs.") @cache(cacheIdentity: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductsByIdIdentity")
category (
id: Int @doc(description: "Id of the category.")
): CategoryTree
Expand Down