From dd3aa3873c752394d5a3c37834005f916ab94e36 Mon Sep 17 00:00:00 2001 From: Zbigniew Kuras Date: Sat, 12 May 2018 14:54:52 +0200 Subject: [PATCH 1/6] GraphQL - Added sort by options to Products GraphQL type --- .../Model/Resolver/Products.php | 35 +++++++++++++++++-- app/code/Magento/GraphQl/etc/schema.graphqls | 11 ++++++ .../GraphQl/Catalog/ProductSearchTest.php | 13 +++++++ 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php index cc791ce780c1..ad0cea010934 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php @@ -53,12 +53,23 @@ class Products implements ResolverInterface * @var Layer\DataProvider\Filters */ private $filtersDataProvider; + + /** + * @var \Magento\Catalog\Model\Config + */ + private $catalogConfig; + + /** + * @var \Magento\Store\Model\StoreManagerInterface + */ + private $storeManager; /** * @param Builder $searchCriteriaBuilder * @param Search $searchQuery * @param Filter $filterQuery * @param ValueFactory $valueFactory + * @param \Magento\Catalog\Model\Config $catalogConfig */ public function __construct( Builder $searchCriteriaBuilder, @@ -66,7 +77,9 @@ public function __construct( Filter $filterQuery, SearchFilter $searchFilter, ValueFactory $valueFactory, - \Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider + \Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider, + \Magento\Catalog\Model\Config $catalogConfig, + \Magento\Store\Model\StoreManagerInterface $storeManager ) { $this->searchCriteriaBuilder = $searchCriteriaBuilder; $this->searchQuery = $searchQuery; @@ -74,6 +87,8 @@ public function __construct( $this->searchFilter = $searchFilter; $this->valueFactory = $valueFactory; $this->filtersDataProvider = $filtersDataProvider; + $this->catalogConfig = $catalogConfig; + $this->storeManager = $storeManager; } /** @@ -118,14 +133,28 @@ public function resolve( ); } + $options = $this->catalogConfig->getAttributeUsedForSortByArray(); + + $sortFields = [ + 'default' => $this->catalogConfig->getProductListDefaultSortBy($this->storeManager->getStore()->getId()), + 'options' => [] + ]; + + $sortFields['options'][] = ['key' => 'position', 'label' => 'Position']; + foreach ($this->catalogConfig->getAttributesUsedForSortBy() as $attribute) { + $sortFields['options'][] = ['key' => $attribute->getAttributeCode(), 'label' => $attribute->getStoreLabel()]; + } + $data = [ 'total_count' => $searchResult->getTotalCount(), 'items' => $searchResult->getProductsSearchResult(), 'page_info' => [ 'page_size' => $searchCriteria->getPageSize(), - 'current_page' => $currentPage + 'current_page' => $currentPage, + 'sort_fields' => $sortFields, ], - 'filters' => $this->filtersDataProvider->getData($layerType) + 'filters' => $this->filtersDataProvider->getData($layerType), + ]; $result = function () use ($data) { diff --git a/app/code/Magento/GraphQl/etc/schema.graphqls b/app/code/Magento/GraphQl/etc/schema.graphqls index ffdf5511b749..4e6bb1cc32ef 100644 --- a/app/code/Magento/GraphQl/etc/schema.graphqls +++ b/app/code/Magento/GraphQl/etc/schema.graphqls @@ -25,9 +25,20 @@ input FilterTypeInput @doc(description: "FilterTypeInput specifies which action type SearchResultPageInfo @doc(description: "SearchResultPageInfo provides navigation for the query response") { page_size: Int @doc(description: "Specifies the maximum number of items to return") current_page: Int @doc(description: "Specifies which page of results to return") + sort_fields: SortFields @doc(description: "An object that includes the default sort field and all available sort fields") } enum SortEnum @doc(description: "This enumeration indicates whether to return results in ascending or descending order") { ASC DESC } + +type SortField { + key: String @doc(description: "Attribute code of sort field") + label: String @doc(description: "Label of sort field") +} + +type SortFields @doc(description: "SortFields contains a default value for sort fields and all available sort fields") { + default: String @doc(description: "Default value of sort fields") + options: [SortField] @doc(description: "Available sort fields") +} \ No newline at end of file diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php index b95e0f933ea0..54380bf79937 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php @@ -511,6 +511,15 @@ public function testQueryProductsInCurrentPageSortedByPriceASC() { page_size current_page + sort_fields + { + default + options + { + key + label + } + } } } } @@ -530,6 +539,10 @@ public function testQueryProductsInCurrentPageSortedByPriceASC() $this->assertProductItems($filteredChildProducts, $response); $this->assertEquals(4, $response['products']['page_info']['page_size']); $this->assertEquals(1, $response['products']['page_info']['current_page']); + $this->assertArrayHasKey('sort_fields', $response['products']['page_info']); + $this->assertArrayHasKey('options', $response['products']['page_info']['sort_fields']); + $this->assertArrayHasKey('default', $response['products']['page_info']['sort_fields']); + $this->assertEquals('position', $response['products']['page_info']['sort_fields']['default']); } /** From 02d6a22a52f96e79e6b3baa1847bb224b824bc36 Mon Sep 17 00:00:00 2001 From: Zbigniew Kuras Date: Sat, 12 May 2018 16:13:11 +0200 Subject: [PATCH 2/6] GraphQL - Added missing constructor doc block type for StoreManagerInterface --- app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php index ad0cea010934..02a5284f74c8 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php @@ -70,6 +70,7 @@ class Products implements ResolverInterface * @param Filter $filterQuery * @param ValueFactory $valueFactory * @param \Magento\Catalog\Model\Config $catalogConfig + * @param \Magento\Store\Model\StoreManagerInterface $storeManager */ public function __construct( Builder $searchCriteriaBuilder, From 9035d2951561dad0760f2bd3d6732b6da7422db0 Mon Sep 17 00:00:00 2001 From: Zbigniew Kuras Date: Wed, 16 May 2018 20:06:37 +0200 Subject: [PATCH 3/6] GraphQL - Created separate resolver for sort_fields --- .../Resolver/Category/SortFieldDefault.php | 64 +++++++++++++++++++ .../Resolver/Category/SortFieldsOptions.php | 61 ++++++++++++++++++ .../Model/Resolver/Products.php | 33 +--------- app/code/Magento/GraphQl/etc/schema.graphqls | 4 +- 4 files changed, 130 insertions(+), 32 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFieldDefault.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFieldsOptions.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFieldDefault.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFieldDefault.php new file mode 100644 index 000000000000..37b9d5f9c5e0 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFieldDefault.php @@ -0,0 +1,64 @@ +valueFactory = $valueFactory; + $this->catalogConfig = $catalogConfig; + $this->storeManager = $storeManager; + } + + /** + * {@inheritDoc} + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) : Value + { + $sortFieldDefault = $this->catalogConfig->getProductListDefaultSortBy($this->storeManager->getStore()->getId()); + + $result = function () use ($sortFieldDefault) { + return $sortFieldDefault; + }; + + return $this->valueFactory->create($result); + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFieldsOptions.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFieldsOptions.php new file mode 100644 index 000000000000..b644fa10a21c --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFieldsOptions.php @@ -0,0 +1,61 @@ +valueFactory = $valueFactory; + $this->catalogConfig = $catalogConfig; + } + + /** + * {@inheritDoc} + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) : Value + { + $sortFieldsOptions = [ + ['key' => 'position', 'label' => 'Position'] + ]; + foreach ($this->catalogConfig->getAttributesUsedForSortBy() as $attribute) { + $sortFieldsOptions[] = ['key' => $attribute->getAttributeCode(), 'label' => $attribute->getStoreLabel()]; + } + + $result = function () use ($sortFieldsOptions) { + return $sortFieldsOptions; + }; + + return $this->valueFactory->create($result); + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php index 02a5284f74c8..f696c52cf684 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php @@ -53,24 +53,12 @@ class Products implements ResolverInterface * @var Layer\DataProvider\Filters */ private $filtersDataProvider; - - /** - * @var \Magento\Catalog\Model\Config - */ - private $catalogConfig; - - /** - * @var \Magento\Store\Model\StoreManagerInterface - */ - private $storeManager; /** * @param Builder $searchCriteriaBuilder * @param Search $searchQuery * @param Filter $filterQuery * @param ValueFactory $valueFactory - * @param \Magento\Catalog\Model\Config $catalogConfig - * @param \Magento\Store\Model\StoreManagerInterface $storeManager */ public function __construct( Builder $searchCriteriaBuilder, @@ -78,9 +66,7 @@ public function __construct( Filter $filterQuery, SearchFilter $searchFilter, ValueFactory $valueFactory, - \Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider, - \Magento\Catalog\Model\Config $catalogConfig, - \Magento\Store\Model\StoreManagerInterface $storeManager + \Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider ) { $this->searchCriteriaBuilder = $searchCriteriaBuilder; $this->searchQuery = $searchQuery; @@ -88,8 +74,6 @@ public function __construct( $this->searchFilter = $searchFilter; $this->valueFactory = $valueFactory; $this->filtersDataProvider = $filtersDataProvider; - $this->catalogConfig = $catalogConfig; - $this->storeManager = $storeManager; } /** @@ -134,25 +118,14 @@ public function resolve( ); } - $options = $this->catalogConfig->getAttributeUsedForSortByArray(); - - $sortFields = [ - 'default' => $this->catalogConfig->getProductListDefaultSortBy($this->storeManager->getStore()->getId()), - 'options' => [] - ]; - - $sortFields['options'][] = ['key' => 'position', 'label' => 'Position']; - foreach ($this->catalogConfig->getAttributesUsedForSortBy() as $attribute) { - $sortFields['options'][] = ['key' => $attribute->getAttributeCode(), 'label' => $attribute->getStoreLabel()]; - } - + $data = [ 'total_count' => $searchResult->getTotalCount(), 'items' => $searchResult->getProductsSearchResult(), 'page_info' => [ 'page_size' => $searchCriteria->getPageSize(), 'current_page' => $currentPage, - 'sort_fields' => $sortFields, + 'sort_fields' => [], ], 'filters' => $this->filtersDataProvider->getData($layerType), diff --git a/app/code/Magento/GraphQl/etc/schema.graphqls b/app/code/Magento/GraphQl/etc/schema.graphqls index 4e6bb1cc32ef..0c6d41a3051e 100644 --- a/app/code/Magento/GraphQl/etc/schema.graphqls +++ b/app/code/Magento/GraphQl/etc/schema.graphqls @@ -39,6 +39,6 @@ type SortField { } type SortFields @doc(description: "SortFields contains a default value for sort fields and all available sort fields") { - default: String @doc(description: "Default value of sort fields") - options: [SortField] @doc(description: "Available sort fields") + default: String @doc(description: "Default value of sort fields") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\SortFieldDefault") + options: [SortField] @doc(description: "Available sort fields") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\SortFieldsOptions") } \ No newline at end of file From d804babe4d2c5cf71e0c46b72221f566df24978b Mon Sep 17 00:00:00 2001 From: Zbigniew Kuras Date: Wed, 16 May 2018 21:04:35 +0200 Subject: [PATCH 4/6] GraphQL - Removed unnecessary empty lines. --- app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php index f696c52cf684..70c3f1c00b27 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php @@ -118,7 +118,6 @@ public function resolve( ); } - $data = [ 'total_count' => $searchResult->getTotalCount(), 'items' => $searchResult->getProductsSearchResult(), @@ -128,7 +127,6 @@ public function resolve( 'sort_fields' => [], ], 'filters' => $this->filtersDataProvider->getData($layerType), - ]; $result = function () use ($data) { From 9962c66890db9fb5f58e09da995b6ecf502c6d88 Mon Sep 17 00:00:00 2001 From: Zbigniew Kuras Date: Thu, 17 May 2018 22:44:05 +0200 Subject: [PATCH 5/6] GraphQL - Created one resolver for sort_fields. Added tests. --- .../{SortFieldDefault.php => SortFields.php} | 23 +++++-- .../Resolver/Category/SortFieldsOptions.php | 61 ------------------- app/code/Magento/GraphQl/etc/schema.graphqls | 8 +-- .../GraphQl/Catalog/ProductSearchTest.php | 5 +- 4 files changed, 25 insertions(+), 72 deletions(-) rename app/code/Magento/CatalogGraphQl/Model/Resolver/Category/{SortFieldDefault.php => SortFields.php} (67%) delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFieldsOptions.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFieldDefault.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFields.php similarity index 67% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFieldDefault.php rename to app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFields.php index 37b9d5f9c5e0..2b482f51df61 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFieldDefault.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFields.php @@ -14,9 +14,9 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** - * Retrieves the sort field default value + * Retrieves the sort fields data */ -class SortFieldDefault implements ResolverInterface +class SortFields implements ResolverInterface { /** * @var ValueFactory @@ -41,7 +41,8 @@ class SortFieldDefault implements ResolverInterface public function __construct( ValueFactory $valueFactory, \Magento\Catalog\Model\Config $catalogConfig, - \Magento\Store\Model\StoreManagerInterface $storeManager + \Magento\Store\Model\StoreManagerInterface $storeManager, + \Magento\Catalog\Model\Category\Attribute\Source\Sortby $ss ) { $this->valueFactory = $valueFactory; $this->catalogConfig = $catalogConfig; @@ -53,10 +54,20 @@ public function __construct( */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) : Value { - $sortFieldDefault = $this->catalogConfig->getProductListDefaultSortBy($this->storeManager->getStore()->getId()); + $sortFieldsOptions = [ + ['value' => 'position', 'label' => 'Position'] + ]; + foreach ($this->catalogConfig->getAttributesUsedForSortBy() as $attribute) { + $sortFieldsOptions[] = ['value' => $attribute->getAttributeCode(), 'label' => $attribute->getStoreLabel()]; + } - $result = function () use ($sortFieldDefault) { - return $sortFieldDefault; + $data = [ + 'default' => $this->catalogConfig->getProductListDefaultSortBy($this->storeManager->getStore()->getId()), + 'options' => $sortFieldsOptions, + ]; + + $result = function () use ($data) { + return $data; }; return $this->valueFactory->create($result); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFieldsOptions.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFieldsOptions.php deleted file mode 100644 index b644fa10a21c..000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFieldsOptions.php +++ /dev/null @@ -1,61 +0,0 @@ -valueFactory = $valueFactory; - $this->catalogConfig = $catalogConfig; - } - - /** - * {@inheritDoc} - */ - public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) : Value - { - $sortFieldsOptions = [ - ['key' => 'position', 'label' => 'Position'] - ]; - foreach ($this->catalogConfig->getAttributesUsedForSortBy() as $attribute) { - $sortFieldsOptions[] = ['key' => $attribute->getAttributeCode(), 'label' => $attribute->getStoreLabel()]; - } - - $result = function () use ($sortFieldsOptions) { - return $sortFieldsOptions; - }; - - return $this->valueFactory->create($result); - } -} diff --git a/app/code/Magento/GraphQl/etc/schema.graphqls b/app/code/Magento/GraphQl/etc/schema.graphqls index 0c6d41a3051e..5446e99c4c31 100644 --- a/app/code/Magento/GraphQl/etc/schema.graphqls +++ b/app/code/Magento/GraphQl/etc/schema.graphqls @@ -25,7 +25,7 @@ input FilterTypeInput @doc(description: "FilterTypeInput specifies which action type SearchResultPageInfo @doc(description: "SearchResultPageInfo provides navigation for the query response") { page_size: Int @doc(description: "Specifies the maximum number of items to return") current_page: Int @doc(description: "Specifies which page of results to return") - sort_fields: SortFields @doc(description: "An object that includes the default sort field and all available sort fields") + 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") } enum SortEnum @doc(description: "This enumeration indicates whether to return results in ascending or descending order") { @@ -34,11 +34,11 @@ enum SortEnum @doc(description: "This enumeration indicates whether to return re } type SortField { - key: String @doc(description: "Attribute code of sort field") + value: String @doc(description: "Attribute code of sort field") label: String @doc(description: "Label of sort field") } type SortFields @doc(description: "SortFields contains a default value for sort fields and all available sort fields") { - default: String @doc(description: "Default value of sort fields") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\SortFieldDefault") - options: [SortField] @doc(description: "Available sort fields") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\SortFieldsOptions") + default: String @doc(description: "Default value of sort fields") + options: [SortField] @doc(description: "Available sort fields") } \ No newline at end of file diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php index 54380bf79937..49371973f100 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php @@ -516,7 +516,7 @@ public function testQueryProductsInCurrentPageSortedByPriceASC() default options { - key + value label } } @@ -543,6 +543,9 @@ public function testQueryProductsInCurrentPageSortedByPriceASC() $this->assertArrayHasKey('options', $response['products']['page_info']['sort_fields']); $this->assertArrayHasKey('default', $response['products']['page_info']['sort_fields']); $this->assertEquals('position', $response['products']['page_info']['sort_fields']['default']); + $this->assertArrayHasKey('value', $response['products']['page_info']['sort_fields']['options'][0]); + $this->assertArrayHasKey('label', $response['products']['page_info']['sort_fields']['options'][0]); + $this->assertEquals(['value'=>'position', 'label' => 'Position'], $response['products']['page_info']['sort_fields']['options'][0]); } /** From 1855062ceed5d8a1fb8822ab4fc8649d2d5e8080 Mon Sep 17 00:00:00 2001 From: Zbigniew Kuras Date: Fri, 18 May 2018 21:40:45 +0200 Subject: [PATCH 6/6] GraphQL - moved sort_fields to Products object. Some fixes --- .../Model/Resolver/Category/SortFields.php | 23 +++++++++------ .../CatalogGraphQl/etc/schema.graphqls | 11 ++++++++ app/code/Magento/GraphQl/etc/schema.graphqls | 11 -------- .../GraphQl/Catalog/ProductSearchTest.php | 28 +++++++++---------- 4 files changed, 40 insertions(+), 33 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFields.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFields.php index 2b482f51df61..ca68b2991011 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFields.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/SortFields.php @@ -32,21 +32,28 @@ class SortFields implements ResolverInterface * @var \Magento\Store\Model\StoreManagerInterface */ private $storeManager; + + /** + * @var \Magento\Catalog\Model\Category\Attribute\Source\Sortby + */ + private $sortbyAttributeSource; /** * @param ValueFactory $valueFactory * @param \Magento\Catalog\Model\Config $catalogConfig * @param \Magento\Store\Model\StoreManagerInterface $storeManager + * @oaram \Magento\Catalog\Model\Category\Attribute\Source\Sortby $sortbyAttributeSource */ public function __construct( ValueFactory $valueFactory, \Magento\Catalog\Model\Config $catalogConfig, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Catalog\Model\Category\Attribute\Source\Sortby $ss + \Magento\Catalog\Model\Category\Attribute\Source\Sortby $sortbyAttributeSource ) { $this->valueFactory = $valueFactory; $this->catalogConfig = $catalogConfig; $this->storeManager = $storeManager; + $this->sortbyAttributeSource = $sortbyAttributeSource; } /** @@ -54,13 +61,13 @@ public function __construct( */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) : Value { - $sortFieldsOptions = [ - ['value' => 'position', 'label' => 'Position'] - ]; - foreach ($this->catalogConfig->getAttributesUsedForSortBy() as $attribute) { - $sortFieldsOptions[] = ['value' => $attribute->getAttributeCode(), 'label' => $attribute->getStoreLabel()]; - } - + $sortFieldsOptions = $this->sortbyAttributeSource->getAllOptions(); + array_walk( + $sortFieldsOptions, + function (&$option) { + $option['label'] = (string)$option['label']; + } + ); $data = [ 'default' => $this->catalogConfig->getProductListDefaultSortBy($this->storeManager->getStore()->getId()), 'options' => $sortFieldsOptions, diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index ca1ff7865431..9a9e114a06d1 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -402,6 +402,7 @@ type Products @doc(description: "The Products object is the top-level object ret 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") filters: [LayerFilter] @doc(description: "Layered navigation filters array") + 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") } 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.") { @@ -521,3 +522,13 @@ interface LayerFilterItemInterface @typeResolver(class: "Magento\\CatalogGraphQl type LayerFilterItem implements LayerFilterItemInterface { } + +type SortField { + value: String @doc(description: "Attribute code of sort field") + label: String @doc(description: "Label of sort field") +} + +type SortFields @doc(description: "SortFields contains a default value for sort fields and all available sort fields") { + default: String @doc(description: "Default value of sort fields") + options: [SortField] @doc(description: "Available sort fields") +} diff --git a/app/code/Magento/GraphQl/etc/schema.graphqls b/app/code/Magento/GraphQl/etc/schema.graphqls index 5446e99c4c31..37ca2d8d7b37 100644 --- a/app/code/Magento/GraphQl/etc/schema.graphqls +++ b/app/code/Magento/GraphQl/etc/schema.graphqls @@ -25,20 +25,9 @@ input FilterTypeInput @doc(description: "FilterTypeInput specifies which action type SearchResultPageInfo @doc(description: "SearchResultPageInfo provides navigation for the query response") { page_size: Int @doc(description: "Specifies the maximum number of items to return") current_page: Int @doc(description: "Specifies which page of results to return") - 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") } enum SortEnum @doc(description: "This enumeration indicates whether to return results in ascending or descending order") { ASC DESC -} - -type SortField { - value: String @doc(description: "Attribute code of sort field") - label: String @doc(description: "Label of sort field") -} - -type SortFields @doc(description: "SortFields contains a default value for sort fields and all available sort fields") { - default: String @doc(description: "Default value of sort fields") - options: [SortField] @doc(description: "Available sort fields") } \ No newline at end of file diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php index 49371973f100..65e044a5f005 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php @@ -511,14 +511,14 @@ public function testQueryProductsInCurrentPageSortedByPriceASC() { page_size current_page - sort_fields + } + sort_fields + { + default + options { - default - options - { - value - label - } + value + label } } } @@ -539,13 +539,13 @@ public function testQueryProductsInCurrentPageSortedByPriceASC() $this->assertProductItems($filteredChildProducts, $response); $this->assertEquals(4, $response['products']['page_info']['page_size']); $this->assertEquals(1, $response['products']['page_info']['current_page']); - $this->assertArrayHasKey('sort_fields', $response['products']['page_info']); - $this->assertArrayHasKey('options', $response['products']['page_info']['sort_fields']); - $this->assertArrayHasKey('default', $response['products']['page_info']['sort_fields']); - $this->assertEquals('position', $response['products']['page_info']['sort_fields']['default']); - $this->assertArrayHasKey('value', $response['products']['page_info']['sort_fields']['options'][0]); - $this->assertArrayHasKey('label', $response['products']['page_info']['sort_fields']['options'][0]); - $this->assertEquals(['value'=>'position', 'label' => 'Position'], $response['products']['page_info']['sort_fields']['options'][0]); + $this->assertArrayHasKey('sort_fields', $response['products']); + $this->assertArrayHasKey('options', $response['products']['sort_fields']); + $this->assertArrayHasKey('default', $response['products']['sort_fields']); + $this->assertEquals('position', $response['products']['sort_fields']['default']); + $this->assertArrayHasKey('value', $response['products']['sort_fields']['options'][0]); + $this->assertArrayHasKey('label', $response['products']['sort_fields']['options'][0]); + $this->assertEquals('position', $response['products']['sort_fields']['options'][0]['value']); } /**