Skip to content

Commit

Permalink
Merge pull request #48 from magento/issue_20
Browse files Browse the repository at this point in the history
Include 'products' in category query
  • Loading branch information
gelanivishal committed May 28, 2018
2 parents 166dd61 + a9e5d85 commit 9506e9b
Show file tree
Hide file tree
Showing 3 changed files with 413 additions and 0 deletions.
107 changes: 107 additions & 0 deletions app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CatalogGraphQl\Model\Resolver\Category;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\Resolver\Value;
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\GraphQl\Query\Resolver\Argument\SearchCriteria\Builder;
use Magento\CatalogGraphQl\Model\Resolver\Products\Query\Filter;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;

/**
* Category products resolver, used by GraphQL endpoints to retrieve products assigned to a category
*/
class Products implements ResolverInterface
{
/** @var \Magento\Catalog\Api\ProductRepositoryInterface */
private $productRepository;

/** @var Builder */
private $searchCriteriaBuilder;

/** @var Filter */
private $filterQuery;

/** @var ValueFactory */
private $valueFactory;

/**
* @param ProductRepositoryInterface $productRepository
* @param Builder $searchCriteriaBuilder
* @param Filter $filterQuery
* @param ValueFactory $valueFactory
*/
public function __construct(
ProductRepositoryInterface $productRepository,
Builder $searchCriteriaBuilder,
Filter $filterQuery,
ValueFactory $valueFactory
) {
$this->productRepository = $productRepository;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->filterQuery = $filterQuery;
$this->valueFactory = $valueFactory;
}

/**
* {@inheritdoc}
*/
public function resolve(
Field $field,
$context,
ResolveInfo $info,
array $value = null,
array $args = null
): Value {
$args['filter'] = [
'category_ids' => [
'eq' => $value['id']
]
];
$searchCriteria = $this->searchCriteriaBuilder->build($field->getName(), $args);
$searchCriteria->setCurrentPage($args['currentPage']);
$searchCriteria->setPageSize($args['pageSize']);
$searchResult = $this->filterQuery->getResult($searchCriteria, $info);

//possible division by 0
if ($searchCriteria->getPageSize()) {
$maxPages = ceil($searchResult->getTotalCount() / $searchCriteria->getPageSize());
} else {
$maxPages = 0;
}

$currentPage = $searchCriteria->getCurrentPage();
if ($searchCriteria->getCurrentPage() > $maxPages && $searchResult->getTotalCount() > 0) {
$currentPage = new GraphQlInputException(
__(
'currentPage value %1 specified is greater than the number of pages available.',
[$maxPages]
)
);
}

$data = [
'total_count' => $searchResult->getTotalCount(),
'items' => $searchResult->getProductsSearchResult(),
'page_info' => [
'page_size' => $searchCriteria->getPageSize(),
'current_page' => $currentPage
]
];

$result = function () use ($data) {
return $data;
};

return $this->valueFactory->create($result);
}
}
11 changes: 11 additions & 0 deletions app/code/Magento/CatalogGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,11 @@ interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model
updated_at: String @doc(description: "Timestamp indicating when the category was updated")
product_count: Int @doc(description: "The number of products in the category")
default_sort_by: String @doc(description: "The attribute to use for sorting")
products(
pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."),
currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."),
sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.")
): CategoryProducts @doc(description: "The list of products assigned to the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products")
}

type CustomizableRadioOption implements CustomizableOptionInterface @doc(description: "CustomizableRadioOption contains information about a set of radio buttons that are defined as part of a customizable option") {
Expand Down Expand Up @@ -406,6 +411,12 @@ type Products @doc(description: "The Products object is the top-level object ret
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")
}

type CategoryProducts @doc(description: "The category products object returned in the Category query") {
items: [ProductInterface] @doc(description: "An array of products that are assigned to the category")
page_info: SearchResultPageInfo @doc(description: "An object that includes the page_info and currentPage values specified in the query")
total_count: Int @doc(description: "The number of products returned")
}

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.") {
name: FilterTypeInput @doc(description: "The product name. Customers use this name to identify the product.")
sku: FilterTypeInput @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer")
Expand Down
Loading

0 comments on commit 9506e9b

Please sign in to comment.