Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit 9506e9b

Browse files
authored
Merge pull request #48 from magento/issue_20
Include 'products' in category query
2 parents 166dd61 + a9e5d85 commit 9506e9b

File tree

3 files changed

+413
-0
lines changed

3 files changed

+413
-0
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
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\Resolver\Category;
9+
10+
use Magento\Catalog\Api\ProductRepositoryInterface;
11+
use Magento\Framework\GraphQl\Config\Element\Field;
12+
use Magento\Framework\GraphQl\Query\Resolver\Value;
13+
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
14+
use Magento\Framework\GraphQl\Query\ResolverInterface;
15+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
16+
use Magento\Framework\GraphQl\Query\Resolver\Argument\SearchCriteria\Builder;
17+
use Magento\CatalogGraphQl\Model\Resolver\Products\Query\Filter;
18+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
19+
20+
/**
21+
* Category products resolver, used by GraphQL endpoints to retrieve products assigned to a category
22+
*/
23+
class Products implements ResolverInterface
24+
{
25+
/** @var \Magento\Catalog\Api\ProductRepositoryInterface */
26+
private $productRepository;
27+
28+
/** @var Builder */
29+
private $searchCriteriaBuilder;
30+
31+
/** @var Filter */
32+
private $filterQuery;
33+
34+
/** @var ValueFactory */
35+
private $valueFactory;
36+
37+
/**
38+
* @param ProductRepositoryInterface $productRepository
39+
* @param Builder $searchCriteriaBuilder
40+
* @param Filter $filterQuery
41+
* @param ValueFactory $valueFactory
42+
*/
43+
public function __construct(
44+
ProductRepositoryInterface $productRepository,
45+
Builder $searchCriteriaBuilder,
46+
Filter $filterQuery,
47+
ValueFactory $valueFactory
48+
) {
49+
$this->productRepository = $productRepository;
50+
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
51+
$this->filterQuery = $filterQuery;
52+
$this->valueFactory = $valueFactory;
53+
}
54+
55+
/**
56+
* {@inheritdoc}
57+
*/
58+
public function resolve(
59+
Field $field,
60+
$context,
61+
ResolveInfo $info,
62+
array $value = null,
63+
array $args = null
64+
): Value {
65+
$args['filter'] = [
66+
'category_ids' => [
67+
'eq' => $value['id']
68+
]
69+
];
70+
$searchCriteria = $this->searchCriteriaBuilder->build($field->getName(), $args);
71+
$searchCriteria->setCurrentPage($args['currentPage']);
72+
$searchCriteria->setPageSize($args['pageSize']);
73+
$searchResult = $this->filterQuery->getResult($searchCriteria, $info);
74+
75+
//possible division by 0
76+
if ($searchCriteria->getPageSize()) {
77+
$maxPages = ceil($searchResult->getTotalCount() / $searchCriteria->getPageSize());
78+
} else {
79+
$maxPages = 0;
80+
}
81+
82+
$currentPage = $searchCriteria->getCurrentPage();
83+
if ($searchCriteria->getCurrentPage() > $maxPages && $searchResult->getTotalCount() > 0) {
84+
$currentPage = new GraphQlInputException(
85+
__(
86+
'currentPage value %1 specified is greater than the number of pages available.',
87+
[$maxPages]
88+
)
89+
);
90+
}
91+
92+
$data = [
93+
'total_count' => $searchResult->getTotalCount(),
94+
'items' => $searchResult->getProductsSearchResult(),
95+
'page_info' => [
96+
'page_size' => $searchCriteria->getPageSize(),
97+
'current_page' => $currentPage
98+
]
99+
];
100+
101+
$result = function () use ($data) {
102+
return $data;
103+
};
104+
105+
return $this->valueFactory->create($result);
106+
}
107+
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,11 @@ interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model
376376
updated_at: String @doc(description: "Timestamp indicating when the category was updated")
377377
product_count: Int @doc(description: "The number of products in the category")
378378
default_sort_by: String @doc(description: "The attribute to use for sorting")
379+
products(
380+
pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."),
381+
currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."),
382+
sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.")
383+
): CategoryProducts @doc(description: "The list of products assigned to the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products")
379384
}
380385

381386
type CustomizableRadioOption implements CustomizableOptionInterface @doc(description: "CustomizableRadioOption contains information about a set of radio buttons that are defined as part of a customizable option") {
@@ -406,6 +411,12 @@ type Products @doc(description: "The Products object is the top-level object ret
406411
sort_fields: SortFields @doc(description: "An object that includes the default sort field and all available sort fields") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\SortFields")
407412
}
408413

414+
type CategoryProducts @doc(description: "The category products object returned in the Category query") {
415+
items: [ProductInterface] @doc(description: "An array of products that are assigned to the category")
416+
page_info: SearchResultPageInfo @doc(description: "An object that includes the page_info and currentPage values specified in the query")
417+
total_count: Int @doc(description: "The number of products returned")
418+
}
419+
409420
input ProductFilterInput @doc(description: "ProductFilterInput defines the filters to be used in the search. A filter contains at least one attribute, a comparison operator, and the value that is being searched for.") {
410421
name: FilterTypeInput @doc(description: "The product name. Customers use this name to identify the product.")
411422
sku: FilterTypeInput @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer")

0 commit comments

Comments
 (0)